Index: openacs-4/packages/payflowpro/payflowpro.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/Attic/payflowpro.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/payflowpro.info 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,47 @@ + + + + + PayFlowPro Gateway + PayFlowPro Gateways + f + f + + + + oracle + postgresql + + Janine Sisk + PayFlowPro payment gateway. + furfly.net, LLC + This is a payment gateway for Verisign's PayFlowPro. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: openacs-4/packages/payflowpro/sql/oracle/payflowpro-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/sql/oracle/Attic/payflowpro-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/sql/oracle/payflowpro-create.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1 @@ +@payflowpro-sc-create Index: openacs-4/packages/payflowpro/sql/oracle/payflowpro-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/sql/oracle/Attic/payflowpro-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/sql/oracle/payflowpro-drop.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1 @@ +@payflowpro-sc-drop Index: openacs-4/packages/payflowpro/sql/oracle/payflowpro-sc-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/sql/oracle/Attic/payflowpro-sc-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/sql/oracle/payflowpro-sc-create.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,97 @@ +-- This is an implementation of the PaymentGateway service contract for +-- Verisign's PayFlow Pro payment service + +-- Don't forget to look at valid_uninstalled_bindings and then use +-- acs_sc_binding to create the necessary bindings, at least until this +-- stuff works on Oracle! And you have to restart after you create them, +-- too. + + +declare + foo integer; +begin + foo := acs_sc_impl.new( + 'PaymentGateway', -- impl_contract_name + 'payflowpro', -- impl_name + 'payflowpro' -- impl_owner_name + ); + + foo := acs_sc_impl.new_alias( + 'PaymentGateway', -- impl_contract_name + 'payflowpro', -- impl_name + 'Authorize', -- impl_operation_name + 'payflowpro.Authorize', -- impl_alias + 'TCL' -- impl_pl + ); + + foo := acs_sc_impl.new_alias( + 'PaymentGateway', -- impl_contract_name + 'payflowpro', -- impl_name + 'ChargeCard', -- impl_operation_name + 'payflowpro.ChargeCard', -- impl_alias + 'TCL' -- impl_pl + ); + + foo := acs_sc_impl.new_alias( + 'PaymentGateway', -- impl_contract_name + 'payflowpro', -- impl_name + 'Return', -- impl_operation_name + 'payflowpro.Return', -- impl_alias + 'TCL' -- impl_pl + ); + + foo := acs_sc_impl.new_alias( + 'PaymentGateway', -- impl_contract_name + 'payflowpro', -- impl_name + 'Void', -- impl_operation_name + 'payflowpro.Void', -- impl_alias + 'TCL' -- impl_pl + ); + + foo := acs_sc_impl.new_alias( + 'PaymentGateway', -- impl_contract_name + 'payflowpro', -- impl_name + 'Info', -- impl_operation_name + 'payflowpro.Info', -- impl_alias + 'TCL' -- impl_pl + ); +end; +/ +show errors + +declare + foo integer; +begin + + -- Add the binding + acs_sc_binding.new ( + contract_name => 'PaymentGateway', + impl_name => 'payflowpro' + ); +end; +/ +show errors + + +-- NOTE - this stuff is here because the naming is instance-specific. I'm +-- not sure that is correct; it would be better if it could be part of the +-- PaymentGateway specification. However, for the purposes of an initial +-- release this will do. + +-- In addition to all the usual service contract definitions, we also need +-- a table which will be used to log results of all our operations. The +-- table is modeled after ec_cybercash_log in the old 3.x ecommerce code. +-- I tried to simplify it quite a bit, which means it will probably need more +-- columns added to it when it is actually being used in real life. +-- +create table payflowpro_result_log ( + transaction_id varchar(20), + txn_attempted_type varchar(25), + txn_attempted_time date, + txn_returned_type varchar(25), + errmsg varchar(200), + auth_code varchar(25), + avs_code_zip varchar(3), + avs_code_addr varchar(3), + amount number +); Index: openacs-4/packages/payflowpro/sql/oracle/payflowpro-sc-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/sql/oracle/Attic/payflowpro-sc-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/sql/oracle/payflowpro-sc-drop.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,47 @@ +declare + foo integer; +begin + foo := acs_sc_impl.delete_alias( + 'PaymentGateway', + 'payflowpro', + 'Authorize' + ); + + foo := acs_sc_impl.delete_alias( + 'PaymentGateway', + 'payflowpro', + 'ChargeCard' + ); + + foo := acs_sc_impl.delete_alias( + 'PaymentGateway', + 'payflowpro', + 'Return' + ); + + foo := acs_sc_impl.delete_alias( + 'PaymentGateway', + 'payflowpro', + 'Void' + ); + + foo := acs_sc_impl.delete_alias( + 'PaymentGateway', + 'payflowpro', + 'info' + ); + + acs_sc_binding.delete( + contract_name => 'PaymentGateway', + impl_name => 'payflowpro' + ); + + acs_sc_impl.delete( + 'PaymentGateway', + 'payflowpro' + ); +end; +/ +show errors + +drop table payflowpro_result_log; Index: openacs-4/packages/payflowpro/sql/postgresql/payflowpro-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/sql/postgresql/Attic/payflowpro-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/sql/postgresql/payflowpro-create.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1 @@ +\i payflowpro-sc-create.sql Index: openacs-4/packages/payflowpro/sql/postgresql/payflowpro-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/sql/postgresql/Attic/payflowpro-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/sql/postgresql/payflowpro-drop.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1 @@ +\i payflowpro-sc-drop.sql Index: openacs-4/packages/payflowpro/sql/postgresql/payflowpro-sc-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/sql/postgresql/Attic/payflowpro-sc-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/sql/postgresql/payflowpro-sc-create.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,78 @@ +-- This is an implementation of the PaymentGateway service contract for +-- Verisign's PayFlow Pro payment service + + select acs_sc_impl__new( + 'PaymentGateway', -- impl_contract_name + 'payflowpro', -- impl_name + 'payflowpro' -- impl_owner_name + ); + + select acs_sc_impl_alias__new( + 'PaymentGateway', -- impl_contract_name + 'payflowpro', -- impl_name + 'Authorize', -- impl_operation_name + 'payflowpro.Authorize', -- impl_alias + 'TCL' -- impl_pl + ); + + select acs_sc_impl_alias__new( + 'PaymentGateway', -- impl_contract_name + 'payflowpro', -- impl_name + 'ChargeCard', -- impl_operation_name + 'payflowpro.ChargeCard', -- impl_alias + 'TCL' -- impl_pl + ); + + select acs_sc_impl_alias__new( + 'PaymentGateway', -- impl_contract_name + 'payflowpro', -- impl_name + 'Return', -- impl_operation_name + 'payflowpro.Return', -- impl_alias + 'TCL' -- impl_pl + ); + + select acs_sc_impl_alias__new( + 'PaymentGateway', -- impl_contract_name + 'payflowpro', -- impl_name + 'Void', -- impl_operation_name + 'payflowpro.Void', -- impl_alias + 'TCL' -- impl_pl + ); + + select acs_sc_impl_alias__new( + 'PaymentGateway', -- impl_contract_name + 'payflowpro', -- impl_name + 'Info', -- impl_operation_name + 'payflowpro.Info', -- impl_alias + 'TCL' -- impl_pl + ); + +-- Add the binding + + select acs_sc_binding__new ( + 'PaymentGateway', + 'payflowpro' + ); + +-- NOTE - this stuff is here because the naming is instance-specific. I'm +-- not sure that is correct; it would be better if it could be part of the +-- PaymentGateway specification. However, for the purposes of an initial +-- release this will do. + +-- In addition to all the usual service contract definitions, we also need +-- a table which will be used to log results of all our operations. The +-- table is modeled after ec_cybercash_log in the old 3.x ecommerce code. +-- I tried to simplify it quite a bit, which means it will probably need more +-- columns added to it when it is actually being used in real life. +-- +create table payflowpro_result_log ( + transaction_id varchar(20), + txn_attempted_type varchar(25), + txn_attempted_time timestamp, + txn_returned_type varchar(25), + errmsg varchar(200), + auth_code varchar(25), + avs_code_zip varchar(3), + avs_code_addr varchar(3), + amount numeric +); Index: openacs-4/packages/payflowpro/sql/postgresql/payflowpro-sc-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/sql/postgresql/Attic/payflowpro-sc-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/sql/postgresql/payflowpro-sc-drop.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,41 @@ + select acs_sc_impl_alias__delete( + 'PaymentGateway', + 'payflowpro', + 'Authorize' + ); + + select acs_sc_impl_alias__delete( + 'PaymentGateway', + 'payflowpro', + 'ChargeCard' + ); + + select acs_sc_impl_alias__delete( + 'PaymentGateway', + 'payflowpro', + 'Return' + ); + + select acs_sc_impl_alias__delete( + 'PaymentGateway', + 'payflowpro', + 'Void' + ); + + select acs_sc_impl_alias__delete( + 'PaymentGateway', + 'payflowpro', + 'info' + ); + + select acs_sc_binding__delete( + 'PaymentGateway', + 'payflowpro' + ); + + select acs_sc_impl__delete( + 'PaymentGateway', + 'payflowpro' + ); + +drop table payflowpro_result_log; Index: openacs-4/packages/payflowpro/tcl/payflowpro-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/tcl/Attic/payflowpro-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/tcl/payflowpro-procs.tcl 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,423 @@ +# some helper functions to simplify the main ones below + +# Write the results of the current operation to the database. If it fails, +# log it but don't let the user know about it. +ad_proc -private payflowpro.log_results { + transaction_id + txn_attempted_type + txn_returned_type + errmsg + auth_code + avs_code_zip + avs_code_addr + amount +} { + @author Janine Sisk (janine@furfly.net) +} { + db_transaction { + db_dml insert_transaction_record "" + } on_error { + ns_log Error "Error inserting into payflowpro_result_log for transaction_id $transaction_id: $errmsg" + } +} + +# The heart of it all: stub functions which can be used as a basis for a +# new package - they all return something valid, and you can fill them in +# one by one. Many of the stubs are currently identical, as the whole +# reason for their existence is in the gateway-specific stuff we're not +# implementing here. + +ad_proc -public payflowpro.Authorize { + transaction_id + amount + card_type + card_number + card_exp_month + card_exp_year + card_name + billing_street + billing_city + billing_state + billing_zip + billing_country +} { + @author Janine Sisk (janine@furfly.net) +} { + # 1. Send transaction off to gateway + # + + # set up expected data structure + set args [ns_set new] + set cc_output [ns_set new] + ns_set put $args "amount" [format %0.2f $amount] + ns_set put $args "card-street" $billing_street + ns_set put $args "card-zip" $billing_zip + ns_set put $args "card-number" $card_number + ns_set put $args "card-exp" $card_exp_month/$card_exp_year + ns_set put $args "card-name" $card_name + + cc_send_to_server_21 "mauthonly" $args $cc_output + + set return_code_key "" + set return_message "" + set mstatus "" + set merrmsg "" + set merch_txn "" + set aux_msg "" + set auth_code "" + set avs_code "" + set avs_code_zip "" + set avs_code_addr "" + if { [ns_set size $cc_output] == 0 } { + set return_code_key retry + } else { + set mstatus [ns_set get $cc_output "MStatus"] + set merrmsg [ns_set get $cc_output "MErrMsg"] + set merch_txn [ns_set get $cc_output "merch-txn"] + set auth_code [ns_set get $cc_output "auth-code"] + set avs_code [ns_set get $cc_output "avs-code"] + set aux_msg [ns_set get $cc_output "aux-msg"] + + if { $mstatus == "failure-q-or-cancel" } { + set return_code_key retry + set return_message "$merrmsg $aux_msg" + } elseif { $mstatus == "failure-bad-money" || $mstatus == "failure-hard" } { + set return_code_key failure + set return_message "$merrmsg $aux_msg" + } else { + # the only possibility left is success + if { $avs_code_zip == "Y" && $avs_code_addr == "Y" } { + set avs_code Y + set return_code_key success + } else { + set return_code_key [ad_parameter -package_id [apm_package_id_from_key payflowpro] ActionOnPartialAVS "failure"] + if { $return_code_key == "success" } { + set avs_code Y + } else { + set avs_code N + set return_message "Address Verification Failed" + } + } + } + } + + # 2. Insert into log table + # + payflowpro.log_results $merch_txn 'mauthonly' $mstatus $merrmsg $auth_code $avs_code_zip $avs_code_addr $amount + + # 3. Return result + # + set return_values(response_code) $return_code_key + set return_values(reason) $return_message + set return_values(transaction_id) $merch_txn + return [array get return_values] +} + +ad_proc -public payflowpro.ChargeCard { + transaction_id + amount + card_type + card_number + card_exp_month + card_exp_year + card_name + billing_street + billing_city + billing_state + billing_zip + billing_country +} { + @author Janine Sisk (janine@furfly.net) +} { + # ChargeCard is a wrapper so we can present a consistent interface to + # the end caller. It will just pass on it's parameters to PostAuth, + # AuthCapture or Charge, whichever is appropriate for the implementation + # at hand. Here, we are doing nothing. + + return [payflowpro.PostAuth $transaction_id $amount] +} + +# It's unlikely that a Return will need all this but I can imagine that +# one of the ultra-cheap services might want to validate the card again, +# giving them another chance to catch a bad card. +ad_proc -public payflowpro.Return { + transaction_id + amount + card_type + card_number + card_exp_month + card_exp_year + card_name + billing_street + billing_city + billing_state + billing_zip + billing_country +} { + @author Janine Sisk (janine@furfly.net) +} { + # 1. Send transaction off to gateway + # + + # set up expected data structure + set args [ns_set new] + set cc_output [ns_set new] + ns_set put $args "order-id" $transaction_id + ns_set put $args "amount" [format %0.2f $amount] + + cc_send_to_server_21 "return" $args $cc_output + + set return_code_key "" + set return_message "" + set mstatus "" + set merrmsg "" + set merch_txn "" + set aux_msg "" + set auth_code "" + if { [ns_set size $cc_output] == 0 } { + set return_code_key retry + } else { + set mstatus [ns_set get $cc_output "MStatus"] + set merrmsg [ns_set get $cc_output "MErrMsg"] + set merch_txn [ns_set get $cc_output "merch-txn"] + set auth_code [ns_set get $cc_output "auth-code"] + set aux_msg [ns_set get $cc_output "aux-msg"] + + if { $mstatus == "failure-q-or-cancel" } { + set return_code_key retry + } elseif { $mstatus == "failure-bad-money" || $mstatus == "failure-hard" } { + set return_code_key failure + set return_message "$merrmsg $aux_msg" + } else { + # the only possibility left is success + set return_code_key success + } + } + + # 2. Insert into log table + # + payflowpro.log_results $merch_txn 'return' $mstatus $merrmsg $auth_code "" "" $amount + + # 3. Return result + # + set return_values(response_code) $return_code_key + set return_values(reason) $return_message + set return_values(transaction_id) $merch_txn + return [array get return_values] +} + +# See comment on Return +ad_proc -public payflowpro.Void { + transaction_id + amount + card_type + card_number + card_exp_month + card_exp_year + card_name + billing_street + billing_city + billing_state + billing_zip + billing_country +} { + @author Janine Sisk (janine@furfly.net) +} { + # 1. Send transaction off to gateway + # + + # set up expected data structure + set args [ns_set new] + set cc_output [ns_set new] + ns_set put $args "order-id" $transaction_id + + cc_send_to_server_21 "void" $args $cc_output + + set return_code_key "" + set return_message "" + set mstatus "" + set merrmsg "" + set merch_txn "" + set aux_msg "" + set auth_code "" + if { [ns_set size $cc_output] == 0 } { + set return_code_key retry + } else { + set mstatus [ns_set get $cc_output "MStatus"] + set merrmsg [ns_set get $cc_output "MErrMsg"] + set merch_txn [ns_set get $cc_output "merch-txn"] + set auth_code [ns_set get $cc_output "auth-code"] + set aux_msg [ns_set get $cc_output "aux-msg"] + + if { $mstatus == "failure-q-or-cancel" } { + set return_code_key retry + } elseif { $mstatus == "failure-bad-money" || $mstatus == "failure-hard" } { + set return_code_key failure + set return_message "$merrmsg $aux_msg" + } else { + # the only possibility left is success + set return_code_key success + } + } + + # 2. Insert into log table + # + payflowpro.log_results $merch_txn 'void' $mstatus $merrmsg $auth_code "" "" $amount + + # 3. Return result + # + set return_values(response_code) $return_code_key + set return_values(reason) $return_message + set return_values(transaction_id) $merch_txn + return [array get return_values] +} + +ad_proc -public payflowpro.Info { +} { + @author Janine Sisk (janine@furfly.net) +} { + set info(package_key) payflowpro + set info(version) 1.0 + set info(package_name) "PayFlowPro" + set info(cards_accepted) [ad_parameter -package_id [ad_conn package_id] CreditCardsAccepted ""] + set info(success) [nsv_get payment_gateway_return_codes success] + set info(failure) [nsv_get payment_gateway_return_codes failure] + set info(retry) [nsv_get payment_gateway_return_codes retry] + set info(not_supported) [nsv_get payment_gateway_return_codes not_supported] + set info(not_implemented) [nsv_get payment_gateway_return_codes not_implemented] + + return [array get info] +} + +# These stubs aren't exposed via the API - they are called only by ChargeCard. + +ad_proc -private payflowpro.PostAuth { + transaction_id + {amount ""} +} { + @author Janine Sisk (janine@furfly.net) +} { + # 1. Send transaction off to gateway + # + + # set up expected data structure + set args [ns_set new] + set cc_output [ns_set new] + ns_set put $args "order-id" $transaction_id + ns_set put $args "amount" [format %0.2f $amount] + + cc_send_to_server_21 "postauth" $args $cc_output + + set return_code_key "" + set return_message "" + set mstatus "" + set merrmsg "" + set merch_txn "" + set aux_msg "" + set auth_code "" + if { [ns_set size $cc_output] == 0 } { + set return_code_key retry + } else { + set mstatus [ns_set get $cc_output "MStatus"] + set merrmsg [ns_set get $cc_output "MErrMsg"] + set merch_txn [ns_set get $cc_output "merch-txn"] + set auth_code [ns_set get $cc_output "auth-code"] + set aux_msg [ns_set get $cc_output "aux-msg"] + + if { $mstatus == "failure-q-or-cancel" } { + set return_code_key retry + } elseif { $mstatus == "failure-bad-money" || $mstatus == "failure-hard" } { + set return_code_key failure + set return_message "$merrmsg $aux_msg" + } else { + # the only possibility left is success + set return_code_key success + } + } + + # 2. Insert into log table + # + payflowpro.log_results $merch_txn 'postauth' $mstatus $merrmsg $auth_code "" "" $amount + + # 3. Return result + # + set return_values(response_code) $return_code_key + set return_values(reason) $return_message + set return_values(transaction_id) $merch_txn + return [array get return_values] +} + +ad_proc -private payflowpro.AuthCapture { + transaction_id + amount + card_type + card_number + card_exp_month + card_exp_year + card_name + billing_street + billing_city + billing_state + billing_zip + billing_country +} { + @author Janine Sisk (janine@furfly.net) +} { + # 1. Send transaction off to gateway + # + # Not implemented in this stub. + + # 2. Insert into log table + # + # Not implemented in this stub. + + # 3. Return result + # + # The result which comes back from the gateway will be looked at and then + # the most appropriate of our canned return codes will be used. This + # needs to be done in context, so it will be done in each function instead + # of being split out on its own. + set return_values(response_code) [nsv_get payment_gateway_return_codes not_implemented] + set return_values(reason) "" + set return_values(transaction_id) "" + return [array get return_values] +} + +ad_proc -private payflowpro.Charge { + transaction_id + amount + card_type + card_number + card_exp_month + card_exp_year + card_name + billing_street + billing_city + billing_state + billing_zip + billing_country +} { + @author Janine Sisk (janine@furfly.net) +} { + # 1. Send transaction off to gateway + # + # Not implemented in this stub. + + # 2. Insert into log table + # + # Not implemented in this stub. + + # 3. Return result + # + # The result which comes back from the gateway will be looked at and then + # the most appropriate of our canned return codes will be used. This + # needs to be done in context, so it will be done in each function instead + # of being split out on its own. + # + # In particular, here we will need to check a package parameter to find + # out whether they can be considered authorized if they fail AVS + set return_values(response_code) [nsv_get payment_gateway_return_codes not_implemented] + set return_values(reason) "" + set return_values(transaction_id) "" + return [array get return_values] +} Index: openacs-4/packages/payflowpro/tcl/payflowpro-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/tcl/Attic/payflowpro-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/tcl/payflowpro-procs.xql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,14 @@ + + + + + + + insert into payflowpro_result_log + (transaction_id, txn_attempted_type, txn_attempted_time, txn_returned_type, errmsg, auth_code, avs_code_zip, avs_code_addr, amount) + values + (:transaction_id, :txn_attempted_type, sysdate, :txn_returned_type, :errmsg, :auth_code, :avs_code_zip, :avs_code_addr, :amount) + + + + Index: openacs-4/packages/payflowpro/verisign-module/Makefile =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/verisign-module/Attic/Makefile,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/verisign-module/Makefile 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,37 @@ +##### YOU SHOULD ONLY HAVE TO EDIT THE FOLLOWING VALUES +# AOLserver directory +NS_HOME=AOLSERVERROOT_DIRECTORY + +# Directory where Software Development Kit was unpacked +SDK_HOME=PATH_TO_PAYFLOWPRO_SDK_LIBRARIES + +# Location of the pfpro lib .so file. +SOFILE=PATH_TO_PAYFLOWPRO_SDK_SO_FILE/libpfpro.so +##### NOTHING BELOW THIS LINE SHOULD HAVE TO BE EDITED + + +CC=gcc + +OBJS=verisign.o +MODULE=verisign.so + +NS_CFLAGS = -D__unix__ -D__solaris__ -fpic -I$(NS_HOME)/include +MCK_CFLAGS = -I$(SDK_HOME) + +CFLAGS = -Wall -g $(NS_CFLAGS) $(MCK_CFLAGS) +LIBS = -L$(SDK_HOME) +VERSION=1.0 + +all: verisign.so + +%.o: %.c + $(CC) $(CFLAGS) -c $< + +verisign.so: verisign.o + gcc -Xlinker -dy -Xlinker -G -o verisign.so $(SOFILE) verisign.o $(LDFLAGS) $(LIBS) + +install: verisign.so + cp verisign.so $(NS_HOME)/bin + +clean: + rm -rf *.o *.so *~ core a.out *.tar.gz Index: openacs-4/packages/payflowpro/verisign-module/README =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/verisign-module/Attic/README,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/verisign-module/README 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,46 @@ +*** This version of verisign.so enhanced and modified by Janine Sisk +of furfly.net, LLC (janine@furfly.net) + +This directory contains version 1.0 of an interface to VeriSign for +AOLServer, and is provided as a replacement for the Cybercash module +written by Jin Choi. Please send Brad Duell (bduell@ncacasi.org) +any feedback/modifications you may have. + +This VeriSign interface is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License, as +published by the Free Software Foundation; either version 2, or (at +your option) any later version. + +This software was developed under Linux 2.2 using gcc 2.95.2, +AOLserver 33.13, and the VeriSign SDK 3.00. Other environments or +versions may or may not require changes. + +INSTALLATION +* Unpack the SDK from VeriSign. +* Edit the variables at the top of Makefile and verisign.c. +* Run 'make install'. +* Edit your AOLserver nsd.ini to include + ns_param verisign PATH_TO_VERISIGN_MODULE/verisign.so + under the modules section. +* Restart AOLserver. + +This module defines three Tcl procedures for the AOLserver API: + cc_generate_order_id, returns a unique order ID (not useful if you + are generating keys with an Oracle sequence or whatever) + cc_send_to_server_21, access to the direct VeriSign API documented + in the PayFlow Pro (Version 3.00) Developer's Guide. + cc_do_direct_payment, access to the directpaycredit facility documented + in the PayFlow Pro (Version 3.00) Developer's Guide. + +Usage: + +cc_generate_order_id -> string + +cc_send_to_server_21 (optional server) + Takes two ns_sets, for input and output values. Does not clear + out the output ns_set before filling it with results. + +cc_do_direct_payment (optional server) + Takes two ns_sets, for input and output values. Does not clear + out the output ns_set before filling it with results. + Index: openacs-4/packages/payflowpro/verisign-module/verisign.c =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/verisign-module/Attic/verisign.c,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/verisign-module/verisign.c 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,456 @@ +/* +* +* Module : Verisign.c +* +* Author : Brad Duell (bduell@ncacasi.org) +* Modified for my needs by Janine Sisk (janine*furfly.net) +* Date : October 15th, 2001 +* Modifications done February, 2002 +* Description: Augmentation of cybercash.c Aolserver module, originally +* designed by ArsDigita, LLC and Jin S. Choi. Use of +* same procedural names, using the VeriSign PayFlowPro v.3.00 +* payment processing interface instead. +* Notes : +* +* defines three Tcl procedures for the AOLserver API: +* cc_generate_order_id, returns a unique order ID (not useful if you +* are generating keys with an Oracle sequence or whatever) +* cc_send_to_server_21, access to the direct VeriSign API documented +* in the PayFlow Pro (Version 3.00) Developer's Guide. +* cc_do_direct_payment, access to the directpaycredit facility documented +* in the PayFlow Pro (Version 3.00) Developer's Guide. +* +* COPYRIGHT NOTICE +* +* this software is copyright 2001 by North Central Association CASI +* it is distributed free under the GNU General Public License +* +*/ + +#include +#include +#include + +#include "ns.h" +#include "pfpro.c" + +/***** YOU SHOULD ONLY HAVE TO EDIT THE FOLLOWING GLOBALS */ +char *USER = "USERNAME"; +char *PARTNER = "PARTNERNAME"; +char *PWD = "PASSWORD"; +char *CERTPATH = "PFPRO_CERT_PATH=PATH_TO_YOUR_PFPROCERT(S)"; +char *hostAddress = "payflow.verisign.com"; +int portNum = 443; +/***** NOTHING BELOW THIS LINE SHOULD HAVE TO BE EDITED */ + +DllExport int Ns_ModuleVersion = 1; +static Tcl_CmdProc GenerateOrderIDCmd; +static Tcl_CmdProc SendToServer21Cmd; + +int CC_SUCCESS = 0; + +static int +GenerateOrderIDCmd(ClientData dummy, Tcl_Interp *interp, int argc, char **argv) +{ + struct tm* timerec; + pid_t mypid; + time_t mytime; + + if (argc != 1) { + interp->result = "Usage: cc_generate_order_id"; + return TCL_ERROR; + } + + mytime = time((time_t *) NULL); + mypid = getpid(); + timerec = gmtime(&mytime); + + sprintf(interp->result,"%02d%02d%02d%02d%02d%05d", + timerec->tm_year, timerec->tm_mon + 1, timerec->tm_mday, + timerec->tm_hour, timerec->tm_min, + mypid); + return TCL_OK; +} + +/** + * Takes two ns_set's, input and output. + * Output set is filled with result values. + */ +static int +SendToServer21Cmd(ClientData dummy, Tcl_Interp *interp, int argc, char **argv) +{ + long timeout = 30; + char *proxyAddress = NULL; + int proxyPort = 0; + char *proxyLogon = NULL; + char *proxyPassword = NULL; + int rc,i,context,parmLen; + char rcBuf[1000]; + char *tranResponse; + + /* Arguments to be send to the PayFlowPro server. */ + char parmList[1000] = "USER="; + char str[1000]; + char *AMT = NULL; + char *ACCT = NULL; + char *EXPDATEWHOLE = NULL; + char *EXPDATE = NULL; + char *ZIP = NULL; + char *STREET = NULL; + char *NAME = NULL; + char *ORIGID = NULL; + + /* From the Payflow Pro (v. 3.00) Developer's Guide Transaction Responses. */ +/* char *respRESULT = "1000"; */ + char respPNREF[100]; + char respRESPMSG[100]; + char respAUTHCODE[100]; + char respAVSADDR[2]; + char respAVSZIP[2]; + char *marker = NULL; + + /* The output set that the ACS expects to read from. */ + Ns_Set *output; + + if (!(argc <= 4) && (argc > 5)) { + /* We'll allow 5 arguments in case we're doing test runs... */ + /* In which case the 5th could be an alternate server. */ + interp->result = "Usage: cc_send_to_server_21 "; + return TCL_ERROR; + } + if (argc == 5) { + hostAddress = argv[4]; + } + + output = Ns_TclGetSet(interp, argv[3]); + if (output == NULL) { + interp->result = "Output was not a valid ns_set"; + return TCL_ERROR; + } + + strcat(parmList, USER); + strcat(parmList, "&VENDOR="); + strcat(parmList, USER); + strcat(parmList, "&PARTNER="); + strcat(parmList, PARTNER); + strcat(parmList, "&PWD="); + strcat(parmList, PWD); + strcat(parmList, "&TRXTYPE="); + + /* Let's determine the type of transaction. */ + if (!strcmp(argv[1], "mauthonly") || !strcmp(argv[1], "retry")) { + strcat(parmList, "A"); + } else { + if (!strcmp(argv[1], "charge")) { + strcat(parmList, "S"); + } else { + if (!strcmp(argv[1], "postauth")) { + strcat(parmList, "D"); + } else { + if (!strcmp(argv[1], "return")) { + strcat(parmList, "C"); + } else { + if (!strcmp(argv[1], "void")) { + strcat(parmList, "V"); + } else { + interp->result = "Module does not support or cannot determine transaction type."; + return TCL_ERROR; + } + } + } + } + } + + /* For each item, throw an error only if the value is required + and missing. */ + + /* Here we'll pull the amount of the transaction. */ + strcat(parmList, "&TENDER=C"); + AMT = Ns_SetGet((Ns_TclGetSet(interp, argv[2])), "amount"); + if (AMT == NULL) { + if (!strcmp(argv[1],"charge") || !strcmp(argv[1],"mauthonly")) { + interp->result = "Cannot retrieve tender amount."; + return TCL_ERROR; + } + } else { + sprintf(str,"&AMT=%s",AMT); + strcat(parmList,str); + } + + /* Now we'll grab the street, adding the length to allow or + & or = in the street name.. */ + STREET = Ns_SetGet((Ns_TclGetSet(interp, argv[2])), "card-street"); + if (STREET != NULL) { + sprintf(str,"&STREET[%d]=%s",strlen(STREET),STREET); + strcat(parmList, str); + } + + /* Now we'll grab the zip. */ + ZIP = Ns_SetGet((Ns_TclGetSet(interp, argv[2])), "card-zip"); + if (ZIP != NULL) { + sprintf(str,"&ZIP=%s",ZIP); + strcat(parmList, str); + } + + /* And the name on the card, also allowing for & and = */ + NAME = Ns_SetGet((Ns_TclGetSet(interp, argv[2])), "card-name"); + if (NAME != NULL) { + sprintf(str,"&NAME[%d]=%s",strlen(NAME),NAME); + strcat(parmList, str); + } + + /* Now we'll grab the card number. */ + ACCT = Ns_SetGet((Ns_TclGetSet(interp, argv[2])), "card-number"); + if (ACCT == NULL) { + if (!strcmp(argv[1],"charge") || !strcmp(argv[1],"mauthonly")) { + interp->result = "Cannot retrieve account number."; + return TCL_ERROR; + } + } else { + sprintf(str,"&ACCT=%s",ACCT); + strcat(parmList, str); + } + + /* Now for the expiration date, seperated by a '/'. */ + EXPDATEWHOLE = Ns_SetGet((Ns_TclGetSet(interp, argv[2])), "card-exp"); + if (EXPDATEWHOLE == NULL) { + if (!strcmp(argv[1],"charge") || !strcmp(argv[1],"mauthonly")) { + interp->result = "Cannot retrieve account expiration date."; + return TCL_ERROR; + } + } else { + EXPDATE=strtok(EXPDATEWHOLE, "/"); + if (EXPDATE == NULL) { + sprintf(str,"&EXPDATE=%s",EXPDATEWHOLE); + strcat(parmList, str); + } else { + sprintf(str,"&EXPDATE=%s",EXPDATE); + strcat(parmList, str); + EXPDATE=strtok(NULL, "/"); + strcat(parmList, EXPDATE); + } + } + + /* Now for the transaction_id/order_id. */ + ORIGID = Ns_SetGet((Ns_TclGetSet(interp, argv[2])), "order-id"); + if (ORIGID == NULL) { + if (!strcmp(argv[1],"postauth") || !strcmp(argv[1],"return") || !strcmp(argv[1],"void")) { + interp->result = "Cannot retrieve reference id."; + return TCL_ERROR; + } + } else { + sprintf(str,"&ORIGID=%s",ORIGID); + strcat(parmList, str); + } +Ns_Log(Notice,"J9: parmList = %s", parmList); + + /* Initialize PayFlowPro client. */ + if( pfproInit() ) { + interp->result = "Failed to initialize PayFlowPro client."; + return TCL_ERROR; + } + if( pfproCreateContext(&context, hostAddress, portNum, timeout, proxyAddress, proxyPort, proxyLogon, proxyPassword)) { + interp->result = "Failed to create PayFlowPro context."; + return TCL_ERROR; + } + parmLen = strlen(parmList); + + /* Nullify the end of the parameter list. */ + parmList[parmLen] = '\0'; + + /* Submit Transaction. */ + pfproSubmitTransaction(context, parmList, parmLen, &tranResponse); + +Ns_Log(Notice,"J9: tranResponse = %s", tranResponse); + + /* Get the result code. */ + marker = strstr(tranResponse,"RESULT="); + if (marker) { + i = 0; + marker+=7; + while ((*marker != '&') && (i<=2)) { + rcBuf[i]=*marker; + marker++; + i++; + } + rcBuf[i] = 0; + rc = atoi(rcBuf); + } else + rc = 1; + + /* Get the response message. */ + marker = strstr(tranResponse,"RESPMSG="); + if (marker) { + i = 0; + marker+=8; + while ((*marker != '&') && (*marker != '\0')) { + rcBuf[i]=*marker; + marker++; + i++; + } + rcBuf[i] = 0; + strcpy(respRESPMSG, rcBuf); + } else + respRESPMSG[0] = '\0'; + + /* Get a reference number for this transaction. */ + marker = strstr(tranResponse,"PNREF="); + if (marker) { + i = 0; + marker+=6; + while ((*marker != '&') && (*marker != '\0')) { + rcBuf[i]=*marker; + marker++; + i++; + } + rcBuf[i] = 0; + strcpy(respPNREF, rcBuf); + } else + respPNREF[0] = '\0'; + + if (rc == 0) { + /* Approved */ + + /* Get the authentication code. */ + marker = strstr(tranResponse,"AUTHCODE="); + if (marker) { + i = 0; + marker+=9; + while ((*marker != '&') && (*marker != '\0')) { + rcBuf[i]=*marker; + marker++; + i++; + } + rcBuf[i] = 0; + strcpy(respAUTHCODE, rcBuf); + } else + respAUTHCODE[0] = '\0'; + + /* Get any AVS available. */ + marker = strstr(tranResponse,"AVSZIP="); + if (marker) { + i = 0; + marker+=7; + while ((*marker != '&') && (*marker != '\0')) { + rcBuf[i]=*marker; + marker++; + i++; + } + rcBuf[i] = 0; + strcpy(respAVSZIP, rcBuf); + } else + respAVSZIP[0] = '\0'; + + marker = strstr(tranResponse,"AVSADDR="); + if (marker) { + i = 0; + marker+=8; + while ((*marker != '&') && (*marker != '\0')) { + rcBuf[i]=*marker; + marker++; + i++; + } + rcBuf[i] = 0; + strcpy(respAVSADDR, rcBuf); + } else + respAVSADDR[0] = '\0'; + + /* We know it's a success. Just return applicable codes. */ + Ns_SetPut(output, "MStatus", "success"); + if (!strcmp(argv[1], "mauthonly") || !strcmp(argv[1], "charge") || !strcmp(argv[1], "retry")) { + Ns_SetPut(output, "aux-msg", respRESPMSG); + Ns_SetPut(output, "auth-code", respAUTHCODE); + Ns_SetPut(output, "action-code", "000"); + Ns_SetPut(output, "merch-txn", respPNREF); + if (strlen(respAVSADDR) == 0) { + if (strlen(respAVSZIP) == 0) { + Ns_SetPut(output, "avs-code", "Z"); + } else { + Ns_SetPut(output, "avs-code", respAVSZIP); + } + } else { + Ns_SetPut(output, "avs-code", respAVSADDR); + } + } else { + Ns_SetPut(output, "merch-txn", respPNREF); + Ns_SetPut(output, "aux-msg", respRESPMSG); + } + + /* Complete the transaction. */ + pfproCompleteTransaction(tranResponse); + pfproDestroyContext(context); + } else { + /* Declined. There are a lot of reasons why, but only a few we care about. */ + if (rc == 50 || rc == 23 || rc == 13 || rc == 24 || rc == 2 || rc == 12) { + /* Insufficent Funds or account number problems */ + Ns_SetPut(output, "MStatus", "failure-bad-money"); + } else { + if (rc < 0 || (rc >= 100 && rc <= 104) || rc == 106) { + /* Various communications errors */ + Ns_SetPut(output, "MStatus", "failure-q-or-cancel"); + } else { + /* Default Error Response */ + Ns_SetPut(output, "MStatus", "failure-hard"); + } + } + + /* All of These Errors Get Returned */ + Ns_SetPut(output, "MErrLoc", "smps"); + Ns_SetPut(output, "MErrMsg", respRESPMSG); + Ns_SetPut(output, "merch-txn", respPNREF); + } + + pfproCleanup(); + +Ns_Log(Notice,"J9 Leaving verisign.so: MStatus=%s,MErrMsg=%s,merch-txn=%s",Ns_SetGet(output, "MStatus"),Ns_SetGet(output,"MErrMsg"),Ns_SetGet(output,"merch-txn")); + + return TCL_OK; +} + +/** + * This implementation is included in the SendToServer21Cmd function + * and is included here for compatibility +*/ +static int +DirectPaymentCmd(ClientData dummy, Tcl_Interp *interp, int argc, char **argv) +{ + if (SendToServer21Cmd(dummy, interp, argc, argv)) { + return TCL_OK; + } else { + return TCL_ERROR; + } +} + +static int +VerisignInterpInit(Tcl_Interp *interp, void *context) +{ + Tcl_CreateCommand(interp, "cc_generate_order_id", GenerateOrderIDCmd, NULL, NULL); + Tcl_CreateCommand(interp, "cc_send_to_server_21", SendToServer21Cmd, NULL, NULL); + Tcl_CreateCommand(interp, "cc_do_direct_payment", DirectPaymentCmd, NULL, NULL); + + putenv(CERTPATH); + + return NS_OK; +} + +/* + * This structure is used to pass the critical section + * and enter and leave command names to InitCs function + * through the Ns_TclInitInterps function. + */ +typedef struct { + char *enter; + char *leave; + Ns_CriticalSection *cs; +} CsCtx; + +int +Ns_ModuleInit(char *hServer, char *hModule) +{ + CsCtx ctx; + int status; + + status = Ns_TclInitInterps(hServer, VerisignInterpInit, (void *) &ctx); + + return status; +} Index: openacs-4/packages/payflowpro/www/admin/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/www/admin/Attic/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/www/admin/index.adp 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,8 @@ + +View @package_name@ Transactions + +

View @package_name@ Transactions

+@context_bar@ +
+ +Right now there is only one option here, to view all transactions in the gateway log. In the future, more options will be created, such as viewing transactions by date range and searching for particular transactions. Index: openacs-4/packages/payflowpro/www/admin/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/www/admin/Attic/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/www/admin/index.tcl 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,26 @@ +ad_page_contract { + + Top page of transaction viewer + + @author Janine Sisk + @creation-date 1/13/02 +} { +} -properties { + package_name + context_bar + all_transactions:multirow +} + +# get information about the gateway we're using; this can stay generic +# by use of this method +# +set package_key [ad_conn package_key] +array set info [acs_sc_call PaymentGateway Info [list] $package_key] +set package_name $info(package_name) +set cleaned_package_key [apm_tcl_or_sql_name_from_package_key $package_key] + +# make sure user is authorized +ad_require_permission [ad_conn package_id] "admin" + +# set context bar +set context_bar [ad_context_bar] Index: openacs-4/packages/payflowpro/www/admin/transactions.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/www/admin/Attic/transactions.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/www/admin/transactions.adp 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,36 @@ + +View @package_name@ Transactions + +

View @package_name@ Transactions

+@context_bar@ +
+ +All transactions which have been processed via @package_name@: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
transaction_idtran type senttran timetran type returnederror msgauth codeAVS (zip)AVS (addr)amount
@all_transactions.txn_attempted_time@@all_transactions.txn_attempted_type@@all_transactions.transaction_id@@all_transactions.txn_returned_type@@all_transactions.errmsg@@all_transactions.auth_code@@all_transactions.avs_code_zip@@all_transactions.avs_code_addr@@all_transactions.amount@
Index: openacs-4/packages/payflowpro/www/admin/transactions.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/www/admin/Attic/transactions.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/www/admin/transactions.tcl 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,32 @@ +ad_page_contract { + + Top page of transaction viewer + + @author Janine Sisk + @creation-date 1/13/02 +} { +} -properties { + package_name + context_bar + all_transactions:multirow +} + +# get information about the gateway we're using; this can stay generic +# by use of this method +# +set package_key [ad_conn package_key] +array set info [acs_sc_call PaymentGateway Info [list] $package_key] +set package_name $info(package_name) +set cleaned_package_key [apm_tcl_or_sql_name_from_package_key $package_key] + +# make sure user is authorized +ad_require_permission [ad_conn package_id] "admin" + +# set context bar +set context_bar [ad_context_bar] + +# get data from table +db_multirow all_transactions get_transactions "" + +# This page will eventually allow the user to enter a date range and search +# for keywords, but this will do for now Index: openacs-4/packages/payflowpro/www/admin/transactions.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payflowpro/www/admin/Attic/transactions.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payflowpro/www/admin/transactions.xql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,13 @@ + + + + + + + select * + from ${cleaned_package_key}_result_log + order by txn_attempted_time" + + + + Index: openacs-4/packages/payment-gateway/payment-gateway.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/payment-gateway.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/payment-gateway.info 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,45 @@ + + + + + Payment Gateway + Payment Gateways + f + f + + + + oracle + postgresql + + Janine Sisk + Bart Teeuwisse +

Payment Gateway Service Contract + 2002-05-07 + furfly.net, LLC + This service contract provides an API for modules to interact with a credit card payment service provider. + + + + + + + + + + + + + + + + + + + + + + + + + Index: openacs-4/packages/payment-gateway/sql/oracle/payment-gateway-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/sql/oracle/payment-gateway-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/sql/oracle/payment-gateway-create.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1 @@ +@payment-gateway-sc-create Index: openacs-4/packages/payment-gateway/sql/oracle/payment-gateway-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/sql/oracle/payment-gateway-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/sql/oracle/payment-gateway-drop.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1 @@ +@payment-gateway-sc-drop Index: openacs-4/packages/payment-gateway/sql/oracle/payment-gateway-sc-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/sql/oracle/payment-gateway-sc-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/sql/oracle/payment-gateway-sc-create.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,126 @@ +declare + bar integer; +begin + bar := acs_sc_contract.new ( + 'PaymentGateway', -- contract_name + 'Interface to Credit Card Payment Gateway' -- contract_desc + ); + +-- Authorize gets an authorization to charge. For gateways that support it, +-- this is done when the order is placed, to verify that the card is good. + bar := acs_sc_msg_type.new ( + 'PaymentGateway.Authorize.InputType', + 'transaction_id:integer,amount:string,card_type:string,card_number:string,card_exp_month:string,card_exp_year:string,card_name:string,billing_street:string,billing_city:string,billing_state:string,billing_zip:string,billing_country:string' + ); + + bar := acs_sc_msg_type.new ( + 'PaymentGateway.Authorize.OutputType', + 'response_code:string,reason:string,transaction_id:string' + ); + + bar := acs_sc_operation.new ( + 'PaymentGateway', -- contract_name + 'Authorize', -- operation_name + 'Authorize', -- operation_desc + 'f', -- operation_iscachable_p + 12, -- operation_nargs + 'PaymentGateway.Authorize.InputType', -- operation_inputtype + 'PaymentGateway.Authorize.OutputType' -- operation_outputtype + ); + +-- ChargeCard is a wrapper which may call postauth, authcapture or charge, +-- depending on the needs of the particular gateway. This is sort of gross; +-- the wrapper is needed so that the caller doesn't have to know which gateway +-- it's talking to, but it has a nasty side-effect: a transaction_id will be +-- a required argument, even though it may be replaced by the one assigned by +-- the gateway. I guess there are worse things... The PostAuth, AuthCapture +-- and Charge functions won't be defined in the service contract since they +-- should not be called directly by the end user. + bar := acs_sc_msg_type.new ( + 'PaymentGateway.ChargeCard.InputType', + 'transaction_id:integer,amount:string,card_type:string,card_number:string,card_exp_month:string,card_exp_year:string,card_name:string,billing_street:string,billing_city:string,billing_state:string,billing_zip:string,billing_country:string' + ); + + bar := acs_sc_msg_type.new ( + 'PaymentGateway.ChargeCard.OutputType', + 'response_code:string,reason:string,transaction_id:string' + ); + + bar := acs_sc_operation.new ( + 'PaymentGateway', -- contract_name + 'ChargeCard', -- operation_name + 'ChargeCard', -- operation_desc + 'f', -- operation_iscachable_p + 12, -- operation_nargs + 'PaymentGateway.ChargeCard.InputType', -- operation_inputtype + 'PaymentGateway.ChargeCard.OutputType' -- operation_outputtype + ); + +-- Most of the time you probably don't need to pass in all this info to do +-- a return or void, but since we can't be sure there isn't a service out +-- there that requires it, I've included it here. No harm done if it's not +-- needed + bar := acs_sc_msg_type.new ( + 'PaymentGateway.Return.InputType', + 'transaction_id:integer,amount:string,card_type:string,card_number:string,card_exp_month:string,card_exp_year:string,card_name:string,billing_street:string,billing_city:string,billing_state:string,billing_zip:string,billing_country:string' + ); + + bar := acs_sc_msg_type.new ( + 'PaymentGateway.Return.OutputType', + 'response_code:string,reason:string,transaction_id:string' + ); + + bar := acs_sc_operation.new ( + 'PaymentGateway', -- contract_name + 'Return', -- operation_name + 'Return', -- operation_desc + 'f', -- operation_iscachable_p + 12, -- operation_nargs + 'PaymentGateway.Return.InputType', -- operation_inputtype + 'PaymentGateway.Return.OutputType' -- operation_outputtype + ); + +-- Void is probably the least commonly supported, but it does exist. + bar := acs_sc_msg_type.new ( + 'PaymentGateway.Void.InputType', + 'transaction_id:integer,amount:string,card_type:string,card_number:string,card_exp_month:string,card_exp_year:string,card_name:string,billing_street:string,billing_city:string,billing_state:string,billing_zip:string,billing_country:string' + ); + + bar := acs_sc_msg_type.new ( + 'PaymentGateway.Void.OutputType', + 'response_code:string,reason:string,transaction_id:string' + ); + + bar := acs_sc_operation.new ( + 'PaymentGateway', -- contract_name + 'Void', -- operation_name + 'Void', -- operation_desc + 'f', -- operation_iscachable_p + 12, -- operation_nargs + 'PaymentGateway.Void.InputType', -- operation_inputtype + 'PaymentGateway.Void.OutputType' -- operation_outputtype + ); + +-- return information about us to the caller + bar := acs_sc_msg_type.new ( + 'PaymentGateway.Info.InputType', + '' + ); + + bar := acs_sc_msg_type.new ( + 'PaymentGateway.Info.OutputType', + 'package_key:string,version:version,package_name:string,cards_accepted:string,success:string,failure:string,retry:string,not_supported:string,not_implemented:string' + ); + + bar := acs_sc_operation.new ( + 'PaymentGateway', -- contract_name + 'info', -- operation_name + 'Information about the gateway', -- operation_desc + 'f', -- operation_iscachable_p + 1, -- operation_nargs + 'PaymentGateway.Info.InputType', -- operation_inputtype + 'PaymentGateway.Info.OutputType' -- operation_outputtype + ); +end; +/ +show errors Index: openacs-4/packages/payment-gateway/sql/oracle/payment-gateway-sc-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/sql/oracle/payment-gateway-sc-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/sql/oracle/payment-gateway-sc-drop.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,15 @@ +begin + acs_sc_contract.delete('PaymentGateway'); + acs_sc_msg_type.delete(null,'PaymentGateway.Authorize.InputType'); + acs_sc_msg_type.delete(null,'PaymentGateway.Authorize.OutputType'); + acs_sc_msg_type.delete(null,'PaymentGateway.ChargeCard.InputType'); + acs_sc_msg_type.delete(null,'PaymentGateway.ChargeCard.OutputType'); + acs_sc_msg_type.delete(null,'PaymentGateway.Return.InputType'); + acs_sc_msg_type.delete(null,'PaymentGateway.Return.OutputType'); + acs_sc_msg_type.delete(null,'PaymentGateway.Void.InputType'); + acs_sc_msg_type.delete(null,'PaymentGateway.Void.OutputType'); + acs_sc_msg_type.delete(null,'PaymentGateway.Info.InputType'); + acs_sc_msg_type.delete(null,'PaymentGateway.Info.OutputType'); +end; +/ +show errors Index: openacs-4/packages/payment-gateway/sql/postgresql/payment-gateway-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/sql/postgresql/payment-gateway-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/sql/postgresql/payment-gateway-create.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1 @@ +\i payment-gateway-sc-create.sql \ No newline at end of file Index: openacs-4/packages/payment-gateway/sql/postgresql/payment-gateway-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/sql/postgresql/payment-gateway-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/sql/postgresql/payment-gateway-drop.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1 @@ +\i payment-gateway-sc-drop.sql \ No newline at end of file Index: openacs-4/packages/payment-gateway/sql/postgresql/payment-gateway-sc-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/sql/postgresql/payment-gateway-sc-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/sql/postgresql/payment-gateway-sc-create.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,129 @@ +select acs_sc_contract__new ( + 'PaymentGateway', -- contract_name + 'Interface to Credit Card Payment Gateway' -- contract_desc +); + +-- Authorize gets an authorization to charge. For gateways that support it, +-- this is done when the order is placed, to verify that the card is good. +select acs_sc_msg_type__new ( + 'PaymentGateway.Authorize.InputType', + 'transaction_id:integer,amount:string,card_type:string,card_number:string,card_exp_month:string,card_exp_year:string,card_name:string,billing_street:string,billing_city:string,billing_state:string,billing_zip:string,billing_country:string' +); + +select acs_sc_msg_type__new ( + 'PaymentGateway.Authorize.OutputType', + 'response_code:string,reason:string,transaction_id:string' +); + +select acs_sc_operation__new ( + 'PaymentGateway', -- contract_name + 'Authorize', -- operation_name + 'Authorize', -- operation_desc + 'f', -- operation_iscachable_p + 12, -- operation_nargs + 'PaymentGateway.Authorize.InputType', -- operation_inputtype + 'PaymentGateway.Authorize.OutputType' -- operation_outputtype +); + + +-- ChargeCard is a wrapper which may call postauth, authcapture or charge, +-- depending on the needs of the particular gateway. This is sort of gross; +-- the wrapper is needed so that the caller doesn't have to know which gateway +-- it's talking to, but it has a nasty side-effect: a transaction_id will be +-- a required argument, even though it may be replaced by the one assigned by +-- the gateway. I guess there are worse things... The PostAuth, AuthCapture +-- and Charge functions won't be defined in the service contract since they +-- should not be called directly by the end user. +select acs_sc_msg_type__new ( + 'PaymentGateway.ChargeCard.InputType', + 'transaction_id:integer,amount:string,card_type:string,card_number:string,card_exp_month:string,card_exp_year:string,card_name:string,billing_street:string,billing_city:string,billing_state:string,billing_zip:string,billing_country:string' +); + +select acs_sc_msg_type__new ( + 'PaymentGateway.ChargeCard.OutputType', + 'response_code:string,reason:string,transaction_id:string' +); + +select acs_sc_operation__new ( + 'PaymentGateway', -- contract_name + 'ChargeCard', -- operation_name + 'ChargeCard', -- operation_desc + 'f', -- operation_iscachable_p + 12, -- operation_nargs + 'PaymentGateway.ChargeCard.InputType', -- operation_inputtype + 'PaymentGateway.ChargeCard.OutputType' -- operation_outputtype +); + + +-- Most of the time you probably don't need to pass in all this info to do +-- a return or void, but since we can't be sure there isn't a service out +-- there that requires it, I've included it here. No harm done if it's not +-- needed +select acs_sc_msg_type__new ( + 'PaymentGateway.Return.InputType', + 'transaction_id:integer,amount:string,card_type:string,card_number:string,card_exp_month:string,card_exp_year:string,card_name:string,billing_street:string,billing_city:string,billing_state:string,billing_zip:string,billing_country:string' +); +select acs_sc_msg_type__new ( + 'PaymentGateway.Return.OutputType', + 'response_code:string,reason:string,transaction_id:string' +); + +select acs_sc_operation__new ( + 'PaymentGateway', -- contract_name + 'Return', -- operation_name + 'Return', -- operation_desc + 'f', -- operation_iscachable_p + 12, -- operation_nargs + 'PaymentGateway.Return.InputType', -- operation_inputtype + 'PaymentGateway.Return.OutputType' -- operation_outputtype +); + + +-- Void is probably the least commonly supported, but it does exist. +select acs_sc_msg_type__new ( + 'PaymentGateway.Void.InputType', + 'transaction_id:integer,amount:string,card_type:string,card_number:string,card_exp_month:string,card_exp_year:string,card_name:string,billing_street:string,billing_city:string,billing_state:string,billing_zip:string,billing_country:string' +); + +select acs_sc_msg_type__new ( + 'PaymentGateway.Void.OutputType', + 'response_code:string,reason:string,transaction_id:string' +); + +select acs_sc_operation__new ( + 'PaymentGateway', -- contract_name + 'Void', -- operation_name + 'Void', -- operation_desc + 'f', -- operation_iscachable_p + 12, -- operation_nargs + 'PaymentGateway.Void.InputType', -- operation_inputtype + 'PaymentGateway.Void.OutputType' -- operation_outputtype +); + + +-- return information about us to the caller +select acs_sc_msg_type__new ( + 'PaymentGateway.Info.InputType', + '' +); + +select acs_sc_msg_type__new ( + 'PaymentGateway.Info.OutputType', + 'package_key:string,version:version,package_name:string,cards_accepted:string,success:string,failure:string,retry:string,not_supported:string,not_implemented:string' +); + +select acs_sc_operation__new ( + 'PaymentGateway', -- contract_name + 'Info', -- operation_name + 'Information about the gateway', -- operation_desc + 'f', -- operation_iscachable_p + 1, -- operation_nargs + 'PaymentGateway.Info.InputType', -- operation_inputtype + 'PaymentGateway.Info.OutputType' -- operation_outputtype +); + +select acs_sc_msg_type__new ( + 'PaymentGateway.Info.InputType', + '' +); + Index: openacs-4/packages/payment-gateway/sql/postgresql/payment-gateway-sc-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/sql/postgresql/payment-gateway-sc-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/sql/postgresql/payment-gateway-sc-drop.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,16 @@ +select acs_sc_operation__delete('PaymentGateway','Authorize'); +select acs_sc_msg_type__delete('PaymentGateway.Authorize.InputType'); +select acs_sc_msg_type__delete('PaymentGateway.Authorize.OutputType'); +select acs_sc_operation__delete('PaymentGateway','ChargeCard'); +select acs_sc_msg_type__delete('PaymentGateway.ChargeCard.InputType'); +select acs_sc_msg_type__delete('PaymentGateway.ChargeCard.OutputType'); +select acs_sc_operation__delete('PaymentGateway','Return'); +select acs_sc_msg_type__delete('PaymentGateway.Return.InputType'); +select acs_sc_msg_type__delete('PaymentGateway.Return.OutputType'); +select acs_sc_operation__delete('PaymentGateway','Void'); +select acs_sc_msg_type__delete('PaymentGateway.Void.InputType'); +select acs_sc_msg_type__delete('PaymentGateway.Void.OutputType'); +select acs_sc_operation__delete('PaymentGateway','Info'); +select acs_sc_msg_type__delete('PaymentGateway.Info.InputType'); +select acs_sc_msg_type__delete('PaymentGateway.Info.OutputType'); +select acs_sc_contract__delete('PaymentGateway'); Index: openacs-4/packages/payment-gateway/tcl/payment-gateway-init.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/tcl/payment-gateway-init.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/tcl/payment-gateway-init.tcl 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,9 @@ +# Set up return code values; these are global to all payment gateways +# using this service contract. +ad_after_server_initialization payment-gateway { + nsv_set payment_gateway_return_codes success "success" + nsv_set payment_gateway_return_codes failure "failure" + nsv_set payment_gateway_return_codes retry "failure-retry" + nsv_set payment_gateway_return_codes not_supported "not_supported" + nsv_set payment_gateway_return_codes not_implemented "not_implemented" +} Index: openacs-4/packages/payment-gateway/tcl/payment-gateway-library-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/tcl/payment-gateway-library-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/tcl/payment-gateway-library-procs.tcl 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,62 @@ +# Distributed under the GNU GPL v2 + +ad_library { + + Tcl library for dotlrn-event-registrations + + @author Janine Sisk (janine@furfly.net) + @creation-date 05-07-02 + +} + +namespace eval payment_gateway { + + ad_proc -public clean_card_number { + card_number + } { + Remove any non-numeric characters from card number + } { + regsub -all {([^0-9]*)([0-9]*)} $card_number {\2} card_number + return $card_number + } + + ad_proc -public check_card_type { + user_card_type + } { + Check the card type entered by the user against a list of card types + this website supports. The card type parameter is supplied by the + calling application, ie something like E-Commerce or Shoppe. Don't + add one to payment-gateway or your payment module; only the caller + can adequately specify which cards their particular merchant account + supports + + Return values are: 0 => failure, 1 => success, -1 => card type + parameter not set or set improperly + } { + # get list of cards accepted; if it's not set or is empty, return error + set cards_accepted [ad_parameter -package_id [ad_conn package_id] CreditCardsAccepted ""] + if { [string length $cards_accepted] == 0 } { + return -1 + } + + # we can't fix all formatting errors the site admin might make but + # we can regsub out a few of the most likely. This removes any spaces + # before or after the commas + regsub -all {( )*,( )*} $cards_accepted "," cards_accepted + + # now go through the list, looking for the card type that was + # passed in. Use -nocase since we don't want to get tripped up + # on differences in capitalization. It is, however, the caller's + # responsibility to make sure that the list they specify in the + # parameter and the list they allow the user to choose from uses + # the same syntax! + foreach type [split $cards_accepted ,] { + if { [string compare -nocase $user_card_type $type] == 0 } { + return 1 + } + } + + # since we got here, we know there was no match + return 0 + } +} Index: openacs-4/packages/payment-gateway/www/creditcard-widget.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/www/creditcard-widget.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/www/creditcard-widget.adp 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,43 @@ +

We accept @cards_we_accept@

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Card Number
Expiration Date (MM/YY) /
Card Type
Name on credit card
Billing Address Line 1
Billing Address Line 2
Billing City + Billing State + Billing Zip Code +
(if you live outside the U.S., leave the zip blank)
+ Index: openacs-4/packages/payment-gateway/www/creditcard-widget.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/payment-gateway/www/creditcard-widget.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/payment-gateway/www/creditcard-widget.tcl 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,25 @@ +ad_page_contract { + This is part of the credit card gateway, for obvious reasons, but it + takes it's list of of what cards it can accept from the caller's + package params. + + That means that it's intended to be used only by the caller, and that + the caller must define a package param called CreditCardsAccepted. + That param is *not* part of this package and it's not supposed to be. + Don't try to add one! :) + + @author Janine Sisk, furfly.net LLC (janine@furfly.net) + @cvs-id $Id: creditcard-widget.tcl,v 1.1 2002/06/05 02:32:58 janines Exp $ +} { +} -properties { + cards_we_accept:onevalue + card_list:multirow +} + +set cards_we_accept [ad_parameter -package_id [ad_conn package_id] CreditCardsAccepted ""] +regsub -all {( )*,( )*} $cards_we_accept "," cards_we_accept + +template::multirow create card_list card_type +foreach card_type [split $cards_we_accept ,] { + template::multirow append card_list $card_type +} Index: openacs-4/packages/sample-gateway/sample-gateway.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/sample-gateway/sample-gateway.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/sample-gateway/sample-gateway.info 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,39 @@ + + + + + Sample Gateway + Sample Gateways + f + f + + + + oracle + postgresql + + Janine Sisk +

Sample payment gateway. + furfly.net, LLC + This is a sample payment gateway, suitable for copying to create a real one. + + + + + + + + + + + + + + + + + + + + + Index: openacs-4/packages/sample-gateway/sql/oracle/sample-gateway-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/sample-gateway/sql/oracle/sample-gateway-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/sample-gateway/sql/oracle/sample-gateway-create.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1 @@ +@sample-gateway-sc-create Index: openacs-4/packages/sample-gateway/sql/oracle/sample-gateway-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/sample-gateway/sql/oracle/sample-gateway-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/sample-gateway/sql/oracle/sample-gateway-drop.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1 @@ +@sample-gateway-sc-drop Index: openacs-4/packages/sample-gateway/sql/oracle/sample-gateway-sc-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/sample-gateway/sql/oracle/sample-gateway-sc-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/sample-gateway/sql/oracle/sample-gateway-sc-create.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,89 @@ +-- This is a sample implementation of the PaymentGateway service contract + +declare + foo integer; +begin + foo := acs_sc_impl.new( + 'PaymentGateway', -- impl_contract_name + 'sample-gateway', -- impl_name + 'sample-gateway' -- impl_owner_name + ); + + foo := acs_sc_impl.new_alias( + 'PaymentGateway', -- impl_contract_name + 'sample-gateway', -- impl_name + 'Authorize', -- impl_operation_name + 'sample_gateway.Authorize', -- impl_alias + 'TCL' -- impl_pl + ); + + foo := acs_sc_impl.new_alias( + 'PaymentGateway', -- impl_contract_name + 'sample-gateway', -- impl_name + 'ChargeCard', -- impl_operation_name + 'sample_gateway.ChargeCard', -- impl_alias + 'TCL' -- impl_pl + ); + + foo := acs_sc_impl.new_alias( + 'PaymentGateway', -- impl_contract_name + 'sample-gateway', -- impl_name + 'Return', -- impl_operation_name + 'sample_gateway.Return', -- impl_alias + 'TCL' -- impl_pl + ); + + foo := acs_sc_impl.new_alias( + 'PaymentGateway', -- impl_contract_name + 'sample-gateway', -- impl_name + 'Void', -- impl_operation_name + 'sample_gateway.Void', -- impl_alias + 'TCL' -- impl_pl + ); + + foo := acs_sc_impl.new_alias( + 'PaymentGateway', -- impl_contract_name + 'sample-gateway', -- impl_name + 'info', -- impl_operation_name + 'sample_gateway.info', -- impl_alias + 'TCL' -- impl_pl + ); +end; +/ +show errors + +declare + foo integer; +begin + + -- Add the binding + acs_sc_binding.new ( + contract_name => 'PaymentGateway', + impl_name => 'sample-gateway' + ); +end; +/ +show errors + + +-- NOTE - this stuff is here because the naming is instance-specific. I'm +-- not sure that is correct; it would be better if it could be part of the +-- PaymentGateway specification. However, for the purposes of an initial +-- release this will do. + +-- In addition to all the usual service contract definitions, we also need +-- a table which will be used to log results of all our operations. The +-- table is modeled after ec_cybercash_log in the old 3.x ecommerce code. +-- I tried to simplify it quite a bit, which means it will probably need more +-- columns added to it when it is actually being used in real life. +-- +create table sample_gateway_result_log ( + transaction_id integer not null, + txn_attempted_type varchar(25), + txn_attempted_time date, + txn_returned_type varchar(25), + errmsg varchar(200), + auth_code varchar(25), + avs_code varchar(3), + amount number +); Index: openacs-4/packages/sample-gateway/sql/oracle/sample-gateway-sc-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/sample-gateway/sql/oracle/sample-gateway-sc-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/sample-gateway/sql/oracle/sample-gateway-sc-drop.sql 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,47 @@ +declare + foo integer; +begin + foo := acs_sc_impl.delete_alias( + 'PaymentGateway', + 'sample-gateway', + 'Authorize' + ); + + foo := acs_sc_impl.delete_alias( + 'PaymentGateway', + 'sample-gateway', + 'ChargeCard' + ); + + foo := acs_sc_impl.delete_alias( + 'PaymentGateway', + 'sample-gateway', + 'Return' + ); + + foo := acs_sc_impl.delete_alias( + 'PaymentGateway', + 'sample-gateway', + 'Void' + ); + + foo := acs_sc_impl.delete_alias( + 'PaymentGateway', + 'sample-gateway', + 'info' + ); + + acs_sc_binding.delete( + contract_name => 'PaymentGateway', + impl_name => 'sample-gateway' + ); + + acs_sc_impl.delete( + 'PaymentGateway', + 'sample-gateway' + ); +end; +/ +show errors + +drop table sample_gateway_result_log; Index: openacs-4/packages/sample-gateway/tcl/sample-gateway-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/sample-gateway/tcl/sample-gateway-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/sample-gateway/tcl/sample-gateway-procs.tcl 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,301 @@ +# some helper functions to simplify the ones below + +# Write the results of the current operation to the database. If it fails, +# log it but don't let the user know about it. +ad_proc sample_gateway.log_results { + transaction_id + txn_attempted_type + txn_attempted_time + txn_returned_type + errmsg + auth_code + avs_code_zip + avs_code_addr + amount +} { + @author Janine Sisk; furfly.net, LLC (janine@furfly.net) +} { + if [catch {db_dml do-insert "insert into sample_gateway_result_log +(transaction_id, txn_attempted_type, txn_attempted_time, txn_returned_type, errmsg, auth_code, avs_code_zip, avs_code_addr, amount) +values +(:transaction_id, :txn_attempted_type, :txn_attempted_time, :txn_returned_type, :errmsg, :auth_code, :avs_code_zip, :avs_code_addr, :amount)"} errmsg] { + ns_log Error "Wasn't able to do insert into sample_gateway_result_log for transaction_id $transaction_id; error was $errmsg" + } +} + + +# The heart of it all: stub functions which can be used as a basis for a +# new package - they all return something valid, and you can fill them in +# one by one. Many of the stubs are currently identical, as the whole +# reason for their existence is in the gateway-specific stuff we're not +# implementing here. +# +# They used to all return not_implemented, but that didn't work too well +# for testing purposes, so at least until there is a module specific for +# testing (which there should be, so that occasional failures can be thrown +# in), all procs return success. + +ad_proc sample_gateway.Authorize { + transaction_id + amount + card_type + card_number + card_exp_month + card_exp_year + card_name + billing_street + billing_city + billing_state + billing_zip + billing_country +} { + @author Janine Sisk; furfly.net, LLC (janine@furfly.net) +} { + # 1. Send transaction off to gateway + # + # Not implemented in this stub. + + # 2. Insert into log table + # + # Not implemented in this stub. + + # 3. Return result + # + # The result which comes back from the gateway will be looked at and then + # the most appropriate of our canned return codes will be used. This + # needs to be done in context, so it will be done in each function instead + # of being split out on its own. + # + # In particular, here we will need to check a package parameter to find + # out whether they can be considered authorized if they fail AVS + set return_values(response_code) [nsv_get payment_gateway_return_codes success] + set return_values(reason) "" + set return_values(transaction_id) "" + return [array get return_values] +} + +ad_proc sample_gateway.ChargeCard { + transaction_id + amount + card_type + card_number + card_exp_month + card_exp_year + card_name + billing_street + billing_city + billing_state + billing_zip + billing_country +} { + @author Janine Sisk; furfly.net, LLC (janine@furfly.net) +} { + # ChargeCard is a wrapper so we can present a consistent interface to + # the end caller. It will just pass on it's parameters to PostAuth, + # AuthCapture or Charge, whichever is appropriate for the implementation + # at hand. Here, we are doing nothing. + + # We are returning the transaction_id we were given, but if this + # wasn't just a stub we'd be returning the value that came back from + # the gateway. We'd also be returning the value that was returned. + set return_values(response_code) [nsv_get payment_gateway_return_codes success] + set return_values(reason) "" + set return_values(transaction_id) $transaction_id + return [array get return_values] +} + +# It's unlikely that a Return will need all this but I can imagine that +# one of the ultra-cheap services might want to validate the card again, +# giving them another chance to catch a bad card. +ad_proc sample_gateway.Return { + transaction_id + amount + card_type + card_number + card_exp_month + card_exp_year + card_name + billing_street + billing_city + billing_state + billing_zip + billing_country +} { + @author Janine Sisk; furfly.net, LLC (janine@furfly.net) +} { + # 1. Send transaction off to gateway + # + # Not implemented in this stub. + + # 2. Insert into log table + # + # Not implemented in this stub. + + # 3. Return result + # + # The result which comes back from the gateway will be looked at and then + # the most appropriate of our canned return codes will be used. This + # needs to be done in context, so it will be done in each function instead + # of being split out on its own. + set return_values(response_code) [nsv_get payment_gateway_return_codes success] + set return_values(reason) "" + set return_values(transaction_id) "" + return [array get return_values] +} + +# See comment on Return +ad_proc sample_gateway.Void { + transaction_id + amount + card_type + card_number + card_exp_month + card_exp_year + card_name + billing_street + billing_city + billing_state + billing_zip + billing_country +} { + @author Janine Sisk; furfly.net, LLC (janine@furfly.net) +} { + # 1. Send transaction off to gateway + # + # Not implemented in this stub. + + # 2. Insert into log table + # + # Not implemented in this stub. + + # 3. Return result + # + # The result which comes back from the gateway will be looked at and then + # the most appropriate of our canned return codes will be used. This + # needs to be done in context, so it will be done in each function instead + # of being split out on its own. + set return_values(response_code) [nsv_get payment_gateway_return_codes success] + set return_values(reason) "" + set return_values(transaction_id) "" + return [array get return_values] +} + +ad_proc sample_gateway.Info { +} { + @author Janine Sisk; furfly.net, LLC (janine@furfly.net) +} { + set info(package_key) sample-gateway + set info(version) 1.0 + set info(package_name) "Sample Gateway" + set info(cards_accepted) [ad_parameter -package_id [ad_conn package_id] CreditCardsAccepted ""] + set info(success) [nsv_get payment_gateway_return_codes success] + set info(failure) [nsv_get payment_gateway_return_codes failure] + set info(retry) [nsv_get payment_gateway_return_codes retry] + set info(not_supported) [nsv_get payment_gateway_return_codes not_supported] + set info(not_implemented) [nsv_get payment_gateway_return_codes not_implemented] + + return [array get info] +} + +# These stubs aren't exposed via the API - they are called only by ChargeCard. + +ad_proc sample_gateway.PostAuth { + transaction_id + amount +} { + @author Janine Sisk; furfly.net, LLC (janine@furfly.net) +} { + # 1. Send transaction off to gateway + # + # Not implemented in this stub. + + # 2. Insert into log table + # + # Not implemented in this stub. + + # 3. Return result + # + # The result which comes back from the gateway will be looked at and then + # the most appropriate of our canned return codes will be used. This + # needs to be done in context, so it will be done in each function instead + # of being split out on its own. + set return_values(response_code) [nsv_get payment_gateway_return_codes success] + set return_values(reason) "" + set return_values(transaction_id) "" + return [array get return_values] +} + +ad_proc sample_gateway.AuthCapture { + transaction_id + amount + card_type + card_number + card_exp_month + card_exp_year + card_name + billing_street + billing_city + billing_state + billing_zip + billing_country +} { + @author Janine Sisk; furfly.net, LLC (janine@furfly.net) +} { + # 1. Send transaction off to gateway + # + # Not implemented in this stub. + + # 2. Insert into log table + # + # Not implemented in this stub. + + # 3. Return result + # + # The result which comes back from the gateway will be looked at and then + # the most appropriate of our canned return codes will be used. This + # needs to be done in context, so it will be done in each function instead + # of being split out on its own. + set return_values(response_code) [nsv_get payment_gateway_return_codes success] + set return_values(reason) "" + set return_values(transaction_id) "" + return [array get return_values] +} + +ad_proc sample_gateway.Charge { + transaction_id + amount + card_type + card_number + card_exp_month + card_exp_year + card_name + billing_street + billing_city + billing_state + billing_zip + billing_country +} { + @author Janine Sisk; furfly.net, LLC (janine@furfly.net) +} { + # 1. Send transaction off to gateway + # + # Not implemented in this stub. + + # 2. Insert into log table + # + # Not implemented in this stub. + + # 3. Return result + # + # The result which comes back from the gateway will be looked at and then + # the most appropriate of our canned return codes will be used. This + # needs to be done in context, so it will be done in each function instead + # of being split out on its own. + # + # In particular, here we will need to check a package parameter to find + # out whether they can be considered authorized if they fail AVS + set return_values(response_code) [nsv_get payment_gateway_return_codes success] + set return_values(reason) "" + set return_values(transaction_id) "" + return [array get return_values] +} Index: openacs-4/packages/sample-gateway/www/admin/transactions.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/sample-gateway/www/admin/transactions.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/sample-gateway/www/admin/transactions.adp 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,36 @@ + +View @package_name@ Transactions + +

View @package_name@ Transactions

+@context_bar@ +
+ +All transactions which have been processed via @package_name@: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
transaction_idtran type senttran timetran type returnederror msgauth codeAVS (zip)AVS (addr)amount
@all_transactions.txn_attempted_time@@all_transactions.txn_attempted_type@@all_transactions.transaction_id@@all_transactions.txn_returned_type@@all_transactions.errmsg@@all_transactions.auth_code@@all_transactions.avs_code_zip@@all_transactions.avs_code_addr@@all_transactions.amount@
Index: openacs-4/packages/sample-gateway/www/admin/transactions.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/sample-gateway/www/admin/transactions.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/sample-gateway/www/admin/transactions.tcl 5 Jun 2002 02:32:58 -0000 1.1 @@ -0,0 +1,34 @@ +ad_page_contract { + + Top page of transaction viewer + + @author Janine Sisk + @creation-date 1/13/02 +} { +} -properties { + package_name + context_bar + all_transactions:multirow +} + +# get information about the gateway we're using; this can stay generic +# by use of this method +# +set package_key [ad_conn package_key] +array set info [acs_sc_call PaymentGateway info [list] $package_key] +set package_name $info(package_name) +set cleaned_package_key [tcl_or_sql_name_from_package_key $package_key] + +# make sure user is authorized +ad_require_permission [ad_conn package_id] "admin" + +# set context bar +set context_bar [ad_context_bar] + +# get data from table +db_multirow all_transactions get-trans "select * +from ${cleaned_package_key}_result_log +order by txn_attempted_time" + +# This page will eventually allow the user to enter a date range and search +# for keywords, but this will do for now