Index: openacs-4/packages/ezic-gateway/ezic-gateway.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/ezic-gateway.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/ezic-gateway.info 5 Jan 2005 19:54:10 -0000 1.1 @@ -0,0 +1,57 @@ + + + + + EZIC Gateway package + EZIC Gateway packages + f + t + + + + oracle + postgresql + + Torben Brosten + EZIC merchant payment gateway package + 2004-02-02 + 0 + Package that manages communication between openacs and the EZIC merchant payment gateway. Requires an account with EZIC and a merchant credit card fulfillment account. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: openacs-4/packages/ezic-gateway/sql/postgresql/ezic-gateway-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/sql/postgresql/ezic-gateway-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/sql/postgresql/ezic-gateway-create.sql 5 Jan 2005 19:54:10 -0000 1.1 @@ -0,0 +1,18 @@ +create table ezic_gateway_result_log ( + transaction_id varchar(20) not null, -- trans_id + txn_attempted_type varchar(18), + txn_attempted_time timestamptz, + response varchar(400), + response_code varchar(2), -- ezic status_code to AN response_code + response_reason_code varchar(2), -- ezic status_code + response_reason_text varchar(100), -- ezic auth_msg + auth_code varchar(8), -- ezic auth_code + avs_code varchar(12), -- ezic avs_code + cvv2_code varchar(2), -- billing info verification code (new) + ticket_code varchar(40), -- approval code, no info avail (new) + amount numeric not null +); + +create index ezic_gateway_result_log_transaction_id on ezic_gateway_result_log(transaction_id); + +\i ezic-gateway-sc-create.sql Index: openacs-4/packages/ezic-gateway/sql/postgresql/ezic-gateway-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/sql/postgresql/ezic-gateway-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/sql/postgresql/ezic-gateway-drop.sql 5 Jan 2005 19:54:10 -0000 1.1 @@ -0,0 +1,3 @@ +drop table ezic_gateway_result_log; + +\i ezic-gateway-sc-drop.sql Index: openacs-4/packages/ezic-gateway/sql/postgresql/ezic-gateway-sc-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/sql/postgresql/ezic-gateway-sc-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/sql/postgresql/ezic-gateway-sc-create.sql 5 Jan 2005 19:54:10 -0000 1.1 @@ -0,0 +1,57 @@ +-- This is an EZIC Direct Mode 3.0 implementation of the PaymentGateway +-- service contract (package) + +select acs_sc_impl__new( + 'PaymentGateway', -- impl_contract_name + 'ezic-gateway', -- impl_name + 'ezic-gateway' -- impl_owner_name +); + + +select acs_sc_impl_alias__new( + 'PaymentGateway', -- impl_contract_name + 'ezic-gateway', -- impl_name + 'Authorize', -- impl_operation_name + 'ezic_gateway.authorize', -- impl_alias + 'TCL' -- impl_pl +); + +select acs_sc_impl_alias__new( + 'PaymentGateway', -- impl_contract_name + 'ezic-gateway', -- impl_name + 'ChargeCard', -- impl_operation_name + 'ezic_gateway.chargecard', -- impl_alias + 'TCL' -- impl_pl +); + +select acs_sc_impl_alias__new( + 'PaymentGateway', -- impl_contract_name + 'ezic-gateway', -- impl_name + 'Return', -- impl_operation_name + 'ezic_gateway.return', -- impl_alias + 'TCL' -- impl_pl +); + +select acs_sc_impl_alias__new( + 'PaymentGateway', -- impl_contract_name + 'ezic-gateway', -- impl_name + 'Void', -- impl_operation_name + 'ezic_gateway.void', -- impl_alias + 'TCL' -- impl_pl +); + +select acs_sc_impl_alias__new( + 'PaymentGateway', -- impl_contract_name + 'ezic-gateway', -- impl_name + 'Info', -- impl_operation_name + 'ezic_gateway.info', -- impl_alias + 'TCL' -- impl_pl +); + +-- Add the binding + +select acs_sc_binding__new ( + 'PaymentGateway', + 'ezic-gateway' +); + Index: openacs-4/packages/ezic-gateway/sql/postgresql/ezic-gateway-sc-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/sql/postgresql/ezic-gateway-sc-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/sql/postgresql/ezic-gateway-sc-drop.sql 5 Jan 2005 19:54:10 -0000 1.1 @@ -0,0 +1,45 @@ +select acs_sc_binding__delete( + 'PaymentGateway', + 'ezic-gateway' +); + +select acs_sc_impl_alias__delete( + 'PaymentGateway', + 'ezic-gateway', + 'Authorize' +); + +select acs_sc_impl_alias__delete( + 'PaymentGateway', + 'ezic-gateway', + 'ChargeCard' +); + +select acs_sc_impl_alias__delete( + 'PaymentGateway', + 'ezic-gateway', + 'Return' +); + +select acs_sc_impl_alias__delete( + 'PaymentGateway', + 'ezic-gateway', + 'Void' +); + +select acs_sc_impl_alias__delete( + 'PaymentGateway', + 'ezic-gateway', + 'Info' +); + +select acs_sc_binding__delete( + 'PaymentGateway', + 'ezic-gateway' +); + +select acs_sc_impl__delete( + 'PaymentGateway', + 'ezic-gateway' +); + Index: openacs-4/packages/ezic-gateway/tcl/ezic-gateway-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/tcl/ezic-gateway-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/tcl/ezic-gateway-procs.tcl 5 Jan 2005 19:54:12 -0000 1.1 @@ -0,0 +1,1075 @@ +ad_library { + + Procedures to implement EZIC Direct Mode 3.0 credit card transactions. + + EZIC uses following codes. Others available via documentation. + + # status_codes - ezic respond field + # (authorize.net equivalent response_code) + # + # 1: (1) successful/approved + # T: (1) sucessful Auth-Only + # 0: (2) failure/declined + # D: duplicate (making this an error) + # : (3) error (no ezic gateway equivalent) + + # AVS_codes - ezic gateway response values + # + # DFJMQVXY: Address and ZIP code match + # LWZ: ZIP code match, address is wrong . . . + # ABOP: address match, ZIP code is wrong + # KN: No match, address and ZIP is wrong + # U: No data from issuer/banknet switch + # R: System unable to process + # S: Issuing bank does not support AVS + # E: Error, AVS not supported for your business . . . + # C: (Int'l) Invalid address and ZIP format + # I: (Int'l) Address not verifiable + # G: (Int'l) Global non-verifiable address + # ?: Unrecognized code (none of the above) + # _: No AVS data (_ means ) + + # CVV2_codes - ezic gateway response field values + # + # M: CVV2 match + # N: CVV2 does not match + # P: CVV2 not processed + # S: Card has CVV2, customer says it doesn't + # U: CVV2 data from issuer + # _: No CVV2 data (_ means ) + + # ticket_codes - ezic gateway response field values (unknown) + # XXXXXXXXXXXXXXX : possible response when using test credit card number. + + # tran_types - ezic gateway input field values + # (authorize.net equivalent) + # + # A: (AUTH_ONLY) authorize a card for a specific amount + # S: (AUTH_CAPTURE) authorize a card for amount, and get money + # C: (CREDIT) credit back money to a card, unrelated to a specific sale + # R: (VOID) refund, refund back money from a prior sale. + # D: (PRIOR_AUTH_CAPTURE) capture a prior (A) authorization, making i a Sale + # : (CAPTURE_ONLY) no ezic gateway equivalent + + # EZIC gateway separates billing last name from billing first name + # The authorize.net package uses a combined $card_name + # ecommerce and payment-gateway packages need similarly adapted. + # This package assumes $card_name is formatted like this: + # set card_name "$first_names $last_name" + # Note: the 3 space delimiter + + # EZIC test mode is set via the virtual terminal only. + # the test request flag here indicates add more communication detail to server log + + @author Bart Teeuwisse + @creation-date March 2002 + @author revised by Torben Brosten + @revision-date January 2004 +} + +ad_proc -private ezic_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 +} { + Connect to EZIC to authorize a transaction for the amount + given on the card given. + + @author Bart Teeuwisse + @creation-date March 2002 + @author revised by Torben Brosten + @revision-date January 2004 +} { + # 1. Send transaction off to gateway + + set test_request [ezic_gateway.decode_test_request] + + + + set field_seperator [ad_parameter field_seperator \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] field_seperator]] + set field_encapsulator [ad_parameter field_encapsulator \ + -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] field_encapsulator]] + set referer_url [ad_parameter referer_url \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] referer_url]] + + # Add the Referer to the headers passed on to EZIC + + set header [ns_set new] + ns_set put $header Referer $referer_url + + # Compile the URL for the GET communication with EZIC + + # Basic secure URL and account info. + + set full_url "[ad_parameter ezic_url -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_url]]?account_id=[ns_urlencode [ad_parameter ezic_login -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_login]]]" + # site_tag is optional when there is only one + if {[string length [ad_parameter ezic_sitetag -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_sitetag]]] > 0 } { + append full_url "&site_tag=[ns_urlencode [ad_parameter ezic_sitetag -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_sitetag]]]" + } + + # Set the transaction type to AUTHORIZE ONLY + # EZIC.com will generate and return the transaction_id, which + # will be stored in + # the response_transaction_id. Use the response_transaction_id to + # complete the transaction with a POST_AUTH operation. + + append full_url "&pay_type=C&tran_type=A&amount=[ns_urlencode [format "%0.2f" $amount]]&tax_amount=[ns_urlencode [format "%0.2f" 0]]&ship_amount=[ns_urlencode [format "%0.2f" 0]]&description=[ns_urlencode "ECommerce transaction ID: $transaction_id"]" + + # Set the credit card information. + # EZIC requires separate first and last name fields per bank field checking + # $card_name is hacked field pair in ecommerce to hold first_names and last_name + # delimiter is triple space (for parsing). Defaults to put all in last name if not parsed. + set name_delim [string first " " $card_name] + if {$name_delim < 0 } { + set name_delim 0 + } + set first_names [string trim [string range $card_name 0 $name_delim]] + set last_name [string range $card_name [expr $name_delim + 3 ] end] + append full_url "&card_number=[ns_urlencode $card_number]&card_expire=[ns_urlencode ${card_exp_month}${card_exp_year}]&bill_name1=[ns_urlencode $first_names]&bill_name2=[ns_urlencode $last_name]" + + # Set the billing information. The information will be sent to + # EZIC to run an AVS check. + + append full_url "&bill_street=[ns_urlencode $billing_street]&bill_city=[ns_urlencode $billing_city]&bill_zip=[ns_urlencode $billing_zip]&bill_state=[ns_urlencode $billing_state]&bill_country=[ns_urlencode $billing_country]" + + # Contact EZIC.com and receive the delimited + # response. Timeout after 30 seconds, don't allow any redirects + # and pass a set of custom headers to EZIC.com. + + if {[string equal $test_request "True"]} { + ns_log Notice "MARK -- EZIC TEST AUTH_ONLY outbound full_url = '$full_url'" + } + + if {[catch {set response [ns_httpsget $full_url 30 0 $header]} error_message]} { + if {[string equal $test_request "True"]} { + ns_log Notice "EZIC: Response is: [value_if_exists $error_message]" + } + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "AUTH_ONLY" $error_message 3 "" $error_message "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes retry] + set return(reason) "Transaction $transaction_id AUTH_ONLY failed, could not contact EZIC: $error_message" + set return(transaction_id) $transaction_id + return [array get return] + } else { + + # 2. Insert into log table + + # Decode the response from EZIC.com. Not all fields are + # of interest. See the EZIC documentation: + # https://secure.ezic.com/public/docs/merchant/public/directmode/directmode3.html + # and start of this file for a list of some response codes. + + # make list of fieldname=value pairs + # first pair is blank, because EZIC uses cgi reply + set response_list "\{[string map [list $field_encapsulator$field_seperator$field_encapsulator "\} \{" $field_encapsulator {}] $response]\}" + + # Check that the response from EZIC is a legimate ADC + # response. When EZIC.com has problems the response is + # not a character delimited list but an HTML page. An ADC + # response has 7 elements, plus first blank element is 8. + # Future versions might return more elements. + + set response_list_len [llength $response_list] + + if { $response_list_len < 3 || $response_list_len > 15 } { + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "AUTH_ONLY" $response 3 "" \ + "EZIC gateway might be down, the response was not a list of 7 fields." "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes retry] + set return(reason) "EZIC gateway might be down, the response was not a list of 7 fields." + set return(transaction_id) $transaction_id + return [array get return] + } else { + + # Ezic says they might change the order that fields are presented in response + # so adding lsearch to set elements from arbitrary response list order. + # EZIC uses cgi response format, so set fields to values right of "=" (value may be empty) + # apparently EZIC returns auth_date which we ignore for now + set response_reason_code [string range [lindex $response_list [lsearch $response_list {status_code=*}]] 12 end] + set response_reason_text [string range [lindex $response_list [lsearch $response_list {auth_msg=*}]] 9 end] + set response_auth_code [string range [lindex $response_list [lsearch $response_list {auth_code=*}]] 10 end] + set response_avs_code [string range [lindex $response_list [lsearch $response_list {avs_code=*}]] 9 end] + set response_transaction_id [string range [lindex $response_list [lsearch $response_list {trans_id=*}]] 9 end] + set response_cvv2_code [string range [lindex $response_list [lsearch $response_list {cvv2_code=*}]] 10 end] + set response_ticket_code [string range [lindex $response_list [lsearch $response_list {ticket_code=*}]] 12 end] + + # translate reason_code from status_code to existing authorize.net mapping + if { $response_reason_code == 1 || $response_reason_code == "T" } { + set response_code 1 + } elseif { $response_reason_code == "0" } { + # for status_code values 0 + set response_code 2 + } else { + # must be an error somewhere + set response_code 3 + } + + ezic_gateway.log_results $response_transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "AUTH_ONLY" \ + $response $response_code $response_reason_code $response_reason_text $response_auth_code $response_avs_code $response_cvv2_code $response_ticket_code $amount + + # 3. Return result + return [ezic_gateway.decode_response $transaction_id $response_transaction_id $response_code $response_reason_code $response_reason_text $amount] + } + } +} + +ad_proc -public ezic_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 +} { + ChargeCard is a wrapper so we can present a consistent interface to + the caller. It will just pass on it's parameters to + ezic_gateway.postauth or ezic_gateway.authcapture, + whichever is appropriate for the implementation at hand. + + PostAuth is used when there is a successful authorize transaction in + the ezic_gateway_result_log for transaction_id. AuthCapture will + be used if there is no prior authorize transaction in the log. + + @author Bart Teeuwisse + @creation-date March 2002 + @author revised by Torben Brosten + @revision-date January 2004 + +} { + + # 1. Check for the existence of a prior auth_only for the transaction_id. + + if {[db_0or1row select_auth_only {}]} { + + # 2a. The transaction has been authorized, now mark the transaction for settlement. + + return [ezic_gateway.postauth $transaction_id $auth_code $card_number $card_exp_month $card_exp_year $card_name $amount] + + } else { + + # 2b. This is a new transaction which will be authorized and automatically marked for settlement. + + return [ezic_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] + } +} + +ad_proc -public ezic_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 +} { + Connect to EZIC gateway to refund the amount given to the card given. + The transaction id needs to reference a settled transaction performed + with the same card. + + @author Bart Teeuwisse + @creation-date March 2002 + @author revised by Torben Brosten + @revision-date January 2004 + +} { + + # 1. Send transaction off to gateway + + set test_request [ezic_gateway.decode_test_request] + + set field_seperator [ad_parameter field_seperator \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] field_seperator]] + set field_encapsulator [ad_parameter field_encapsulator \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] field_encapsulator]] + set referer_url [ad_parameter referer_url \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] referer_url]] + + # Add the Referer to the headers passed on to EZIC.com + + set header [ns_set new] + ns_set put $header Referer $referer_url + + if {[string length $card_number] < 2} { + # card_number must have been deleted. Reject transaction + set error_message "Card number not available. Credit transaction rejected." + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "CREDIT" $error_message 3 "" $error_message "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes failure] + set return(reason) "Transaction $transaction_id CREDIT failed. No card number." + set return(transaction_id) $transaction_id + return [array get return] + } + + # Compile the URL for the GET communication with EZIC.com + + # Basic secure URL and account info. + set full_url "[ad_parameter ezic_url -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_url]]?account_id=[ns_urlencode [ad_parameter ezic_login -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_login]]]" + # site_tag is optional when there is only one + if {[string length [ad_parameter ezic_sitetag -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_sitetag]]] > 0 } { + append full_url "&site_tag=[ns_urlencode [ad_parameter ezic_sitetag -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_sitetag]]]" + } + + # Set the transaction type to CREDIT and the transaction id. + + append full_url "&pay_type=C&tran_type=C&amount=[ns_urlencode [format "%0.2f" $amount]]&tax_amount=[ns_urlencode [format "%0.2f" 0]]&ship_amount=[ns_urlencode [format "%0.2f" 0]]&trans_id=$transaction_id" + + # Set the credit card information. + # EZIC requires separate first and last name fields (a bank services field checking requirement) + # $card_name should contain a field pair in ecommerce to hold first_names and last_name + # delimiter is triple space (for parsing). + set name_delim [string first " " $card_name] + if {$name_delim < 0 } { + set name_delim 0 + } + set first_names [string trim [string range $card_name 0 $name_delim]] + set last_name [string range $card_name [expr $name_delim + 3 ] end] + append full_url "&card_number=[ns_urlencode $card_number]&card_expire=[ns_urlencode ${card_exp_month}${card_exp_year}]&bill_name2=[ns_urlencode $last_name]&bill_name1=[ns_urlencode $first_names]" + + # Contact EZIC.com and receive the delimited + # response. Timeout after 30 seconds, don't allow any redirects + # and pass a set of custom headers to EZIC. + + if {[string equal $test_request "True"]} { + ns_log Notice "MARK -- EZIC TEST CREDIT outbound full_url = '$full_url'" + } + + if {[catch {set response [ns_httpsget $full_url 30 0 $header]} error_message]} { + if {[string equal $test_request "True"]} { + ns_log Notice "EZIC: Response is: [value_if_exists $error_message]" + } + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "CREDIT" $error_message 3 "" $error_message "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes retry] + set return(reason) "Transaction $transaction_id CREDIT failed, could not contact EZIC.com: $error_message" + set return(transaction_id) $transaction_id + return [array get return] + } else { + + # 3. Insert into log table + + # Decode the response from EZIC.com. Not all fields are + # of interest. See the EZIC documentation: + # https://secure.ezic.com/public/docs/merchant/public/directmode/directmode3.html + # and start of this file for a list of some response codes. + + set response_list "\{[string map [list $field_encapsulator$field_seperator$field_encapsulator "\} \{" $field_encapsulator {}] $response]\}" + + # Check that the response from EZIC is a legimate ADC + # response. When EZIC.com has problems the response is + # not a character delimited list but an HTML page. An ADC + # response has certainly 7 elements, plus first blank element is 8. Future + # versions might return more elements. + + set response_list_len [llength $response_list] + if { $response_list_len < 3 || $response_list_len > 15 } { + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "CREDIT" $response 3 "" \ + "EZIC gateway might be down, the response was not a list of 7 fields" "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes retry] + set return(reason) "EZIC gateway might be down, the response was not a list of 7 fields." + set return(transaction_id) $transaction_id + return [array get return] + } else { + + # Ezic says they might change the order that fields are presented in response + # so adding lsearch to set elements from arbitrary response list order. + # EZIC uses cgi response format, so set fields to values right of "=" (value may be empty) + # apparently EZIC returns auth_date which we ignore for now + set response_reason_code [string range [lindex $response_list [lsearch $response_list {status_code=*}]] 12 end] + set response_reason_text [string range [lindex $response_list [lsearch $response_list {auth_msg=*}]] 9 end] + set response_auth_code [string range [lindex $response_list [lsearch $response_list {auth_code=*}]] 10 end] + set response_avs_code [string range [lindex $response_list [lsearch $response_list {avs_code=*}]] 9 end] + set response_transaction_id [string range [lindex $response_list [lsearch $response_list {trans_id=*}]] 9 end] + set response_cvv2_code [string range [lindex $response_list [lsearch $response_list {cvv2_code=*}]] 10 end] + set response_ticket_code [string range [lindex $response_list [lsearch $response_list {ticket_code=*}]] 12 end] + + # translate reason_code from status_code to existing authorize.net mapping + if { $response_reason_code == 1 || $response_reason_code == "T" } { + set response_code 1 + } elseif { $response_reason_code == "0" } { + # for status_code values 0 + set response_code 2 + } else { + # must be an error somewhere + set response_code 3 + } + + ezic_gateway.log_results $response_transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "CREDIT" \ + $response $response_code $response_reason_code $response_reason_text $response_auth_code $response_avs_code $response_cvv2_code $response_ticket_code $amount + + # 4. Return result + + return [ezic_gateway.decode_response $transaction_id $response_transaction_id $response_code $response_reason_code $response_reason_text $amount] + } + } +} + +ad_proc -public ezic_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 +} { + Connect to EZIC.com to void the transaction with transaction_id. + + @author Bart Teeuwisse + @creation-date March 2002 + @author revised by Torben Brosten + @revision-date January 2004 + +} { + # 1. Send transaction off to gateway + + set test_request [ezic_gateway.decode_test_request] + + set field_seperator [ad_parameter field_seperator \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] field_seperator]] + set field_encapsulator [ad_parameter field_encapsulator \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] field_encapsulator]] + set referer_url [ad_parameter referer_url \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] referer_url]] + + # EZIC refers to "VOID" as a refund. + + # Add the Referer to the headers passed on to EZIC.com + + set header [ns_set new] + ns_set put $header Referer $referer_url + + if {[string length $card_number] < 2} { + # card_number must have been deleted. Reject transaction + set error_message "Card number not available. VOID transaction rejected." + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "VOID" $error_message 3 "" $error_message "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes failure] + set return(reason) "Transaction $transaction_id VOID failed. No card number." + set return(transaction_id) $transaction_id + return [array get return] + } + + # Compile the URL for the GET communication with EZIC.com + + # Basic secure URL and account info. + set full_url "[ad_parameter ezic_url -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_url]]?account_id=[ns_urlencode [ad_parameter ezic_login -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_login]]]" + # site_tag is optional when there is only one + if {[string length [ad_parameter ezic_sitetag -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_sitetag]]] > 0 } { + append full_url "&site_tag=[ns_urlencode [ad_parameter ezic_sitetag -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_sitetag]]]" + } + + # Set the transaction type to VOID (EZIC: Refund) + + append full_url "&pay_type=C&tran_type=R&amount=[ns_urlencode [format "%0.2f" $amount]]&tax_amount=[ns_urlencode [format "%0.2f" 0]]&ship_amount=[ns_urlencode [format "%0.2f" 0]]&orig_id=$transaction_id" + + # Set the credit card information. + # EZIC requires separate first and last name fields per bank field checking + # $card_name is hacked field pair in ecommerce to hold first_names and last_name + # delimiter is triple space (for parsing). + set name_delim [string first " " $card_name] + if {$name_delim < 0 } { + set name_delim 0 + } + set first_names [string trim [string range $card_name 0 $name_delim]] + set last_name [string range $card_name [expr $name_delim + 3 ] end] + append full_url "&card_number=[ns_urlencode $card_number]&card_expire=[ns_urlencode ${card_exp_month}${card_exp_year}]&bill_name2=[ns_urlencode $last_name]&bill_name1=[ns_urlencode $first_names]" + + # Contact EZIC.com and receive the delimited + # response. Timeout after 30 seconds, don't allow any redirects + # and pass a set of custom headers to EZIC.com + + if {[string equal $test_request "True"]} { + ns_log Notice "MARK -- EZIC TEST VOID outbound full_url = '$full_url'" + } + + if {[catch {set response [ns_httpsget $full_url 30 0 $header]} error_message]} { + if {[string equal $test_request "True"]} { + ns_log Notice "EZIC: Response is: [value_if_exists $error_message]" + } + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "VOID" $error_message 3 "" $error_message "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes retry] + set return(reason) "Transaction $transaction_id VOID failed, could not contact EZIC gateway: $error_message" + set return(transaction_id) $transaction_id + return [array get return] + } else { + + # 2. Insert into log table + + # Decode the response from EZIC.com. Not all fields are + # of interest. See the EZIC documentation: + # https://secure.ezic.com/public/docs/merchant/public/directmode/directmode3.html + # and start of this file for a list of some response codes. + + set response_list "\{[string map [list $field_encapsulator$field_seperator$field_encapsulator "\} \{" $field_encapsulator {}] $response]\}" + + # Check that the response from EZIC.com is a legimate ADC + # response. When EZIC has problems the response is + # not a character delimited list but an HTML page. An ADC + # response has 7 elements, plus first blank element is 8. Future + # versions might return more elements. + + set response_list_len [llength $response_list] + if { $response_list_len < 3 || $response_list_len > 15 } { + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "VOID" $response 3 "" \ + "EZIC gateway might be down, the response was not a character delimited list" "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes retry] + set return(reason) "EZIC gateway might be down, the response was not a character delimited list" + set return(transaction_id) $transaction_id + return [array get return] + } else { + + # Ezic says they might change the order that fields are presented in response + # so adding lsearch to set elements from arbitrary response list order. + # EZIC uses cgi response format, so set fields to values right of "=" (value may be empty) + # apparently EZIC returns auth_date which we ignore for now + set response_reason_code [string range [lindex $response_list [lsearch $response_list {status_code=*}]] 12 end] + set response_reason_text [string range [lindex $response_list [lsearch $response_list {auth_msg=*}]] 9 end] + set response_auth_code [string range [lindex $response_list [lsearch $response_list {auth_code=*}]] 10 end] + set response_avs_code [string range [lindex $response_list [lsearch $response_list {avs_code=*}]] 9 end] + set response_transaction_id [string range [lindex $response_list [lsearch $response_list {trans_id=*}]] 9 end] + set response_cvv2_code [string range [lindex $response_list [lsearch $response_list {cvv2_code=*}]] 10 end] + set response_ticket_code [string range [lindex $response_list [lsearch $response_list {ticket_code=*}]] 12 end] + + # translate reason_code from status_code to existing authorize.net mapping + if { $response_reason_code == 1 || $response_reason_code == "T" } { + set response_code 1 + } elseif { $response_reason_code == "0" } { + # for status_code values 0 + set response_code 2 + } else { + # must be an error somewhere + set response_code 3 + } + + ezic_gateway.log_results $response_transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "VOID" \ + $response $response_code $response_reason_code $response_reason_text $response_auth_code $response_avs_code $response_cvv2_code $response_ticket_code $amount + + # 3. Return result + + return [ezic_gateway.decode_response $transaction_id $response_transaction_id $response_code $response_reason_code $response_reason_text $amount] + } + } +} + +ad_proc -public ezic_gateway.info { +} { + Return information about EZIC.com implementation of the + payment service contract. Returns the package_key, version, package name + cards accepted and a list of return codes. + + @author Bart Teeuwisse + @creation-date March 2002 + @author revised by Torben Brosten + @revision-date January 2004 + +} { + + array set info [list \ + package_key ezic-gateway \ + version [db_string get_package_version {}] \ + package_name [db_string get_package_name {}] \ + cards_accepted [ad_parameter CreditCardsAccepted \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] CreditCardsAccepted]] \ + success [nsv_get payment_gateway_return_codes success] \ + failure [nsv_get payment_gateway_return_codes failure] \ + retry [nsv_get payment_gateway_return_codes retry] \ + not_supported [nsv_get payment_gateway_return_codes not_supported] \ + 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 ezic_gateway.postauth { + transaction_id + auth_code + card_number + card_exp_month + card_exp_year + card_name + amount +} { + Connect to EZIC gateway to PRIOR_AUTH_CAPTURE the transaction with transaction id. + The transaction needs to have been AUTH_ONLY before calling this procedure. + + @author Bart Teeuwisse + @creation-date March 2002 + @author revised by Torben Brosten + @revision-date January 2004 + +} { + # 1. Send transaction off to gateway + + set test_request [ezic_gateway.decode_test_request] + + set field_seperator [ad_parameter field_seperator \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] field_seperator]] + set field_encapsulator [ad_parameter field_encapsulator \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] field_encapsulator]] + set referer_url [ad_parameter referer_url \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] referer_url]] + + # Add the Referer to the headers passed on to EZIC gateway + + set header [ns_set new] + ns_set put $header Referer $referer_url + + if {[string length $card_number] < 2} { + # card_number must have been deleted. Reject transaction + set error_message "Card number not available. PRIOR_AUTH_CAPTURE transaction rejected." + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "PRIOR_AUTH_CAPTURE" $error_message 3 "" $error_message "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes failure] + set return(reason) "Transaction $transaction_id PRIOR_AUTH_CAPTURE failed. No card number." + set return(transaction_id) $transaction_id + return [array get return] + } + + # Compile the URL for the GET communication with EZIC gateway + + # Basic secure URL and account info. + set full_url "[ad_parameter ezic_url -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_url]]?account_id=[ns_urlencode [ad_parameter ezic_login -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_login]]]" + # site_tag is optional when there is only one + if {[string length [ad_parameter ezic_sitetag -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_sitetag]]] > 0 } { + append full_url "&site_tag=[ns_urlencode [ad_parameter ezic_sitetag -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_sitetag]]]" + } + + # Set the transaction type to PRIOR_AUTH_CAPTURE, the transaction_id + # to the id of the transaction that has been authorized and the + # auth_code to the authorization code of that transaction. + + append full_url "&pay_type=C&tran_type=D&amount=[ns_urlencode [format "%0.2f" $amount]]&tax_amount=[ns_urlencode [format "%0.2f" 0]]&ship_amount=[ns_urlencode [format "%0.2f" 0]]&orig_id=$transaction_id" + + # Set the credit card information. + # EZIC requires separate first and last name fields per bank field checking + # $card_name is hacked field pair in ecommerce to hold first_names and last_name + # delimiter is triple space (for parsing). + set name_delim [string first " " $card_name] + if {$name_delim < 0 } { + set name_delim 0 + } + set first_names [string trim [string range $card_name 0 $name_delim]] + set last_name [string range $card_name [expr $name_delim + 3 ] end] + append full_url "&card_number=[ns_urlencode $card_number]&card_expire=[ns_urlencode ${card_exp_month}${card_exp_year}]&bill_name2=[ns_urlencode $last_name]&bill_name1=[ns_urlencode $first_names]" + + # Contact EZIC.com and receive the delimited + # response. Timeout after 30 seconds, don't allow any redirects + # and pass a set of custom headers to EZIC.com + + if {[string equal $test_request "True"]} { + ns_log Notice "MARK -- EZIC TEST PRIOR_AUTH_CAPTURE outbound full_url = '$full_url'" + } + + if {[catch {set response [ns_httpsget $full_url 30 0 $header]} error_message]} { + if {[string equal $test_request "True"]} { + ns_log Notice "EZIC: Response is: [value_if_exists $error_message]" + } + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "PRIOR_AUTH_CAPTURE" $error_message 3 "" \ + $error_message "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes retry] + set return(reason) "Transaction $transaction_id failed, could not contact EZIC gateway: $error_message" + set return(transaction_id) $transaction_id + return [array get return] + } else { + + # 2. Insert into log table + + # Decode the response from EZIC.com. Not all fields are + # of interest. See the EZIC documentation: + # https://secure.ezic.com/public/docs/merchant/public/directmode/directmode3.html + # and start of this file for a list of some response codes. + + set response_list "\{[string map [list $field_encapsulator$field_seperator$field_encapsulator "\} \{" $field_encapsulator {}] $response]\}" + + # Check that the response from EZIC.com is a legimate ADC + # response. When EZIC has problems the response is + # not a character delimited list but an HTML page. An ADC + # response has 7 elements, plus first blank element is 8. Future + # versions might return more elements. + + set response_list_len [llength $response_list] + if { $response_list_len < 3 || $response_list_len > 15 } { + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "PRIOR_AUTH_CAPTURE" $response 3 "" \ + "EZIC gateway might be down, the response was not a character delimited list" "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes retry] + set return(reason) "EZIC gateway might be down, the response was not a character delimited list" + set return(transaction_id) $transaction_id + return [array get return] + } else { + + # Ezic says they might change the order that fields are presented in response + # so adding lsearch to set elements from arbitrary response list order. + # EZIC uses cgi response format, so set fields to values right of "=" (value may be empty) + # apparently EZIC returns auth_date which we ignore for now + set response_reason_code [string range [lindex $response_list [lsearch $response_list {status_code=*}]] 12 end] + set response_reason_text [string range [lindex $response_list [lsearch $response_list {auth_msg=*}]] 9 end] + set response_auth_code [string range [lindex $response_list [lsearch $response_list {auth_code=*}]] 10 end] + set response_avs_code [string range [lindex $response_list [lsearch $response_list {avs_code=*}]] 9 end] + set response_transaction_id [string range [lindex $response_list [lsearch $response_list {trans_id=*}]] 9 end] + set response_cvv2_code [string range [lindex $response_list [lsearch $response_list {cvv2_code=*}]] 10 end] + set response_ticket_code [string range [lindex $response_list [lsearch $response_list {ticket_code=*}]] 12 end] + + # translate reason_code from status_code to existing authorize.net mapping + if { $response_reason_code == 1 || $response_reason_code == "T" } { + set response_code 1 + } elseif { $response_reason_code == "0" } { + # for status_code values 0 + set response_code 2 + } else { + # must be an error somewhere + set response_code 3 + } + + ezic_gateway.log_results $response_transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "PRIOR_AUTH_CAPTURE" \ + $response $response_code $response_reason_code $response_reason_text $response_auth_code $response_avs_code $response_cvv2_code $response_ticket_code $amount + + # 3. Return result + + return [ezic_gateway.decode_response $transaction_id $response_transaction_id $response_code $response_reason_code \ + $response_reason_text $amount] + } + } +} + +ad_proc -private ezic_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 +} { + Connect to EZIC gateway to authorize and schedule the transaction for automatic + settling. No further action is needed to complete the transastion. + + @author Bart Teeuwisse + @creation-date March 2002 + @author revised by Torben Brosten + @revision-date January 2004 + +} { + # 1. Send transaction off to gateway + + set test_request [ezic_gateway.decode_test_request] + + set field_seperator [ad_parameter field_seperator \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] field_seperator]] + set field_encapsulator [ad_parameter field_encapsulator \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] field_encapsulator]] + set referer_url [ad_parameter referer_url \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] referer_url]] + + # Add the Referer to the headers passed on to EZIC gateway + + set header [ns_set new] + ns_set put $header Referer $referer_url + + # Compile the URL for the GET communication with EZIC gateway + + # Basic secure URL and account info. + set full_url "[ad_parameter ezic_url -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_url]]?account_id=[ns_urlencode [ad_parameter ezic_login -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_login]]]" + # site_tag is optional when there is only one + if {[string length [ad_parameter ezic_sitetag -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_sitetag]]] > 0 } { + append full_url "&site_tag=[ns_urlencode [ad_parameter ezic_sitetag -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] ezic_sitetag]]]" + } + + # Set the transaction type to AUTH_CAPTURE + # EZIC will generate the transaction id + # and return. The EZIC gateway transaction id will be stored in + # the response_transaction_id. + + append full_url "&pay_type=C&tran_type=S&amount=[ns_urlencode [format "%0.2f" $amount]]&tax_amount=[ns_urlencode [format "%0.2f" 0]]&ship_amount=[ns_urlencode [format "%0.2f" 0]]&description=[ns_urlencode [ad_parameter "description"]]" + + # Set the credit card information. + # EZIC requires separate first and last name fields per bank field checking + # $card_name is hacked field pair in ecommerce to hold first_names and last_name + # delimiter is triple space (for parsing). + set name_delim [string first " " $card_name] + if {$name_delim < 0 } { + set name_delim 0 + } + set first_names [string trim [string range $card_name 0 $name_delim]] + set last_name [string range $card_name [expr $name_delim + 3 ] end] + append full_url "&card_number=[ns_urlencode $card_number]&card_expire=[ns_urlencode ${card_exp_month}${card_exp_year}]&bill_name2=[ns_urlencode $last_name]&bill_name1=[ns_urlencode $first_names]" + + # Set the billing information. The information will be sent to + # EZIC to run an AVS check. + + append full_url "&bill_street=[ns_urlencode $billing_street]&bill_city=[ns_urlencode $billing_city]&bill_zip=[ns_urlencode $billing_zip]&bill_state=[ns_urlencode $billing_state]&bill_country=[ns_urlencode $billing_country]" + + # Contact EZIC.com and receive the delimited + # response. Timeout after 30 seconds, don't allow any redirects + # and pass a set of custom headers to EZIC.com. + + if {[string equal $test_request "True"]} { + ns_log Notice "MARK -- EZIC TEST AUTH_CAPTURE outbound full_url = '$full_url'" + } + + if {[catch {set response [ns_httpsget $full_url 30 0 $header]} error_message]} { + if {[string equal $test_request "True"]} { + ns_log Notice "EZIC: Response is: [value_if_exists $error_message]" + } + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "AUTH_CAPTURE" $error_message 3 "" \ + $error_message "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes retry] + set return(reason) "Transaction $transaction_id failed, could not contact EZIC gateway: $error_message" + set return(transaction_id) $transaction_id + return [array get return] + } else { + + # 2. Insert into log table + + # Decode the response from EZIC.com. Not all fields are + # of interest. See the EZIC documentation: + # https://secure.ezic.com/public/docs/merchant/public/directmode/directmode3.html + # and start of this file for a list of some response codes. + + set response_list "\{[string map [list $field_encapsulator$field_seperator$field_encapsulator "\} \{" $field_encapsulator {}] $response]\}" + + # Check that the response from EZIC is a legimate ADC + # response. When EZIC.com has problems the response is + # not a character delimited list but an HTML page. An ADC + # response has 7 elements, plus first blank element is 8. Future + # versions might return more elements. + + set response_list_len [llength $response_list] + if { $response_list_len < 3 || $response_list_len > 15 } { + ezic_gateway.log_results $transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "AUTH_CAPTURE" $response 3 "" \ + "EZIC gateway must be down, the response was not a character delimited list" "" "" "" "" $amount + set return(response_code) [nsv_get payment_gateway_return_codes retry] + set return(reason) "EZIC gateway must be down, the response was not a character delimited list" + set return(transaction_id) $transaction_id + return [array get return] + } else { + + # Ezic says they might change the order that fields are presented in response + # so adding lsearch to set elements from arbitrary response list order. + # EZIC uses cgi response format, so set fields to values right of "=" (value may be empty) + # apparently EZIC returns auth_date which we ignore for now + set response_reason_code [string range [lindex $response_list [lsearch $response_list {status_code=*}]] 12 end] + set response_reason_text [string range [lindex $response_list [lsearch $response_list {auth_msg=*}]] 9 end] + set response_auth_code [string range [lindex $response_list [lsearch $response_list {auth_code=*}]] 10 end] + set response_avs_code [string range [lindex $response_list [lsearch $response_list {avs_code=*}]] 9 end] + set response_transaction_id [string range [lindex $response_list [lsearch $response_list {trans_id=*}]] 9 end] + set response_cvv2_code [string range [lindex $response_list [lsearch $response_list {cvv2_code=*}]] 10 end] + set response_ticket_code [string range [lindex $response_list [lsearch $response_list {ticket_code=*}]] 12 end] + + # translate reason_code from status_code to existing authorize.net mapping + if { $response_reason_code == 1 || $response_reason_code == "T" } { + set response_code 1 + } elseif { $response_reason_code == "0" } { + # for status_code values 0 + set response_code 2 + } else { + # must be an error somewhere + set response_code 3 + } + + authorize_gateway.log_results $response_transaction_id "[clock format [clock seconds] -format "%D %H:%M:%S"]" "AUTH_CAPTURE" \ + $response $response_code $response_reason_code $response_reason_text $response_auth_code $response_avs_code $amount + + # 3. Return result + + return [ezic_gateway.decode_response $transaction_id $response_transaction_id $response_code $response_reason_code $response_reason_text $amount] + } + } +} + +ad_proc -private ezic_gateway.decode_response { + transaction_id + response_transaction_id + response_code + response_reason_code + response_reason_text + amount +} { + Decode the response from EZIC gateway. + Map EZIC gateway Direct Mode 3 response codes to standardized payment service + contract response codes. + + @author Bart Teeuwisse + @creation-date March 2002 + @author revised by Torben Brosten + @revision-date January 2004 +} { + # decode the response code and the reason code. + + switch -exact $response_code { + "1" { + set return(response_code) [nsv_get payment_gateway_return_codes success] + set return(reason) "Transaction $response_transaction_id has been approved." + set return(transaction_id) $response_transaction_id + return [array get return] + } + "2" { + set return(response_code) [nsv_get payment_gateway_return_codes failure] + set return(reason) "Transaction $response_transaction_id has been declined: $response_reason_text" + set return(transaction_id) $transaction_id + return [array get return] + } + "3" { + + # Some of the transactions that encounter an + # error while being processed can be retried in a + # little while. See the EZIC documentation: + # https://secure.ezic.com/public/docs/merchant/public/directmode/directmode3.html + # and start of this file for a list of some response codes. + + # skipping this part (No error re-try codes from EZIC) + + # All other transactions failed indefinitely. + + set return(response_code) [nsv_get payment_gateway_return_codes failure] + set return(reason) "There has been an error processing transaction $response_transaction_id: $response_reason_text" + set return(transaction_id) $transaction_id + return [array get return] + } + default { + set return(response_code) [nsv_get payment_gateway_return_codes not_implemented] + set return(reason) "EZIC gateway returned an unknown response_code: $response_reason_code" + set return(transaction_id) $transaction_id + return [array get return] + } + } +} + +ad_proc -private ezic_gateway.decode_test_request { +} { + Set test_request to True/False based on the test_request parameter of the + package. This prevents errors due to incorrect values of the test_request + parameter + + @author Bart Teeuwisse + @creation-date March 2002 +} { + + switch -exact [string tolower [ad_parameter test_request \ + -default [ad_parameter -package_id [apm_package_id_from_key ezic-gateway] test_request]]] { + "0" - + "n" - + "no" - + "false" { + set test_request "False" + } + "1" - + "y" - + "yes" - + "true" { + set test_request "True" + } + default { + set test_request "False" + } + } + return $test_request +} + +ad_proc -private ezic_gateway.log_results { + transaction_id + txn_attempted_time + txn_attempted_type + response + response_code + response_reason_code + response_reason_text + auth_code + avs_code + cvv2_code + ticket_code + amount +} { + Write the results of the current operation to the database. If it fails, + log it but don't let the user know about it. + + @author Bart Teeuwisse + @author revised by Torben Brosten + @revision-date January 2004 + +} { + set ezic_url [ad_parameter ezic_url \ + -default [ad_parameter \ + -package_id [apm_package_id_from_key ezic-gateway] \ + ezic_url]] + # catch non nulls as zero so errors can be logged. + if {[string length $transaction_id] <= 1} { + set $transaction_id 999999 + } + if {[string length $amount] == 0} { + set amount 0.00 + } + + # now filter and process + + if {[string length $response] > 400} { + ns_log Notice "Response from $ezic_url exceeds database field length. Trimming response '$response' to 400 characters." + set response [string range $response 0 399] + } + if {[string length $response_reason_text] > 100} { + ns_log Notice "Response reason text from $ezic_url exceeds database field length. Trimming response reason text '$response_reason_text' to 100 characters." + set response_reason_text [string range $response_reason_text 0 99] + } + + if {[string length $response_code] > 2} { + ns_log Error "re: $ezic_url response_code=${response_code} --too long for ezic_gateway_result_log transaction_id ${transaction_id}" + set response_code [string range $response_code 0 1] + } + if {[string length $response_reason_code] > 2} { + ns_log Error "re: response_reason_code=${response_reason_code} --too long for ezic_gateway_result_log transaction_id ${transaction_id}" + set response_reason_code [string range $response_reason_code 0 1] + } + if {[string length $cvv2_code] > 2} { + ns_log Error "re: cvv2_code=${cvv2_code} --too long for ezic_gateway_result_log transaction_id ${transaction_id}" + set cvv2_code [string range $cvv2_code 0 1] + } + + + if [catch {db_dml do-insert " + insert into ezic_gateway_result_log + (transaction_id, txn_attempted_time, txn_attempted_type, response, response_code, response_reason_code, response_reason_text, auth_code, avs_code, cvv2_code, ticket_code, amount) + values + (:transaction_id, :txn_attempted_time, :txn_attempted_type, :response, :response_code, :response_reason_code, :response_reason_text, :auth_code, :avs_code, :cvv2_code, :ticket_code, :amount)"} errmsg] { + ns_log Error "Was not able to insert into ezic_gateway_result_log for transaction_id ${transaction_id}; error was ${errmsg}" + } + +} Index: openacs-4/packages/ezic-gateway/tcl/ezic-gateway-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/tcl/ezic-gateway-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/tcl/ezic-gateway-procs.xql 5 Jan 2005 19:54:12 -0000 1.1 @@ -0,0 +1,45 @@ + + + + + + + select transaction_id, auth_code + from ezic_gateway_result_log + where txn_attempted_type='AUTH_ONLY' + and response_code='1' + and transaction_id=:transaction_id + + + + + + insert into ezic_gateway_result_log + (transaction_id, txn_attempted_type, txn_attempted_time, response, response_code, + response_reason_code, response_reason_text, auth_code, avs_code, cvv2_code, ticket_code, amount) + values + (:transaction_id, :txn_attempted_type, :txn_attempted_time, :response, :response_code, + :response_reason_code, :response_reason_text, :auth_code, :avs_code, :cvv2_code, :ticket_code, :amount) + + + + + + select version_name + from apm_package_versions + where enabled_p = 't' + and package_key = 'ezic-gateway' + + + + + + select instance_name + from apm_packages p, apm_package_versions v + where p.package_key = v.package_key + and v.enabled_p = 't' + and p.package_key = 'ezic-gateway' + + + + Index: openacs-4/packages/ezic-gateway/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/www/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/www/index.adp 5 Jan 2005 19:54:12 -0000 1.1 @@ -0,0 +1,10 @@ + + @title@ + +
@context_bar;noquote@[ Administer ]
+
+ + @context_bar@ + + +

This package has no user pages.

Index: openacs-4/packages/ezic-gateway/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/www/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/www/index.tcl 5 Jan 2005 19:54:12 -0000 1.1 @@ -0,0 +1,40 @@ +ad_page_contract { + + A place holder for access to the admin pages. + + @author Bart Teeuwisse + @modified-by Torben Brosten + @creation-date April 2002 + @modified-date Feb 2004 + +} { +} -properties { + title:onevalue + context_bar:onevalue +} + +# Authenticate the user + +set user_id [ad_maybe_redirect_for_registration] + +# Check for admin privileges + +set package_id [ad_conn package_id] +set admin_p [ad_permission_p $package_id admin] + +# Get the name of the package + +if {[db_0or1row get_package_name " + select p.instance_name + from apm_packages p, apm_package_versions v + where p.package_id = :package_id + and p.package_key = v.package_key + and v.enabled_p = 't'"]} { + set title "$instance_name" +} else { + set title "EZIC Gateway package" +} + +# Set the context bar. + +set context_bar [ad_context_bar] Index: openacs-4/packages/ezic-gateway/www/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/www/index.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/www/index.xql 5 Jan 2005 19:54:12 -0000 1.1 @@ -0,0 +1,15 @@ + + + + + + + select p.instance_name + from apm_packages p, apm_package_versions v + where p.package_id = :package_id + and p.package_key = v.package_key + and v.enabled_p = 't' + + + + Index: openacs-4/packages/ezic-gateway/www/admin/index-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/www/admin/index-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/www/admin/index-postgresql.xql 5 Jan 2005 19:54:12 -0000 1.1 @@ -0,0 +1,32 @@ + + + + postgresql7.1 + + + + txn_attempted_time + '1 days'::interval > now() + + + + + + txn_attempted_time + '7 days'::interval > now() + + + + + + txn_attempted_time + '1 months'::interval > now() + + + + + + select transaction_id, to_char(txn_attempted_time, 'MM-DD-YYYY HH24:MI:SS') as txn_time, txn_attempted_type, response, response_code, response_reason_code, response_reason_text, auth_code, avs_code, amount + from ezic_gateway_result_log + where '1'='1' [ad_dimensional_sql $dimensional] [ad_order_by_from_sort_spec $orderby $table_def] + + + + \ No newline at end of file Index: openacs-4/packages/ezic-gateway/www/admin/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/www/admin/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/www/admin/index.adp 5 Jan 2005 19:54:12 -0000 1.1 @@ -0,0 +1,7 @@ + + @title;noquote@ +
@context_bar;noquote@[ help ]
+ + @dimensional_bar;noquote@ +

@result_table;noquote@

+ Index: openacs-4/packages/ezic-gateway/www/admin/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/www/admin/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/www/admin/index.tcl 5 Jan 2005 19:54:12 -0000 1.1 @@ -0,0 +1,83 @@ +ad_page_contract { + + Lists the log of the results + + @author Bart Teeuwisse + @modified-by Torben Brosten + @creation-date April 2002 + @modified-date February 2004 +} { + {orderby "txn_time*"} +} -properties { + title:onevalue + context_bar:onevalue + dimensional_bar:onevalue +} + +# Authenticate the user + +set user_id [ad_maybe_redirect_for_registration] + +# Check for admin privileges + +set package_id [ad_conn package_id] +set admin_p [ad_permission_p $package_id admin] + +# Get the package name and set the title. + +if {[db_0or1row get_package_name " + select p.instance_name + from apm_packages p, apm_package_versions v + where p.package_id = :package_id + and p.package_key = v.package_key + and v.enabled_p = 't'"]} { + set title "$instance_name Administration" +} else { + set title "Administration" +} + +# Set the context bar. + +set context_bar [ad_context_bar] + +# Dimensional slider definition for narrowing the selection. + +set dimensional { + {response_code "Result" approved { + {approved "approved" {where "[db_map result_approved]"} } + {declined "declined" {where "[db_map result_declined]"} } + {error "error" {where "[db_map result_error]"} } + {any "all" {} } + } } + {transaction "Time of transaction" 1d { + {1d "last 24 hours" {where "[db_map transaction_last_24hours]"}} + {1w "last week" {where "[db_map transaction_last_week]"}} + {1m "last month" {where "[db_map transaction_last_month]"}} + {any "all" {} } + } } +} +set dimensional_bar [ad_dimensional $dimensional] + +# Definition for ad_table. + +set table_def { + {transaction_id "ID" {} {}} + {txn_time "Date" {txn_attempted_time desc} {}} + {txn_attempted_type "Type" {} {}} + {response_code "Result" {} {}} + {response_reason_code "Reason" {} {}} + {response_reason_text "Explanation" no_sort {}} + {auth_code "Authorization" {} {}} + {avs_code "AVS" {} {}} + {response "Verbatim response" no_sort {}} + {amount "Amount" {} {}} +} + +# Create the table to display the results from EZIC gateway + +set result_table [ad_table result_select " + select transaction_id, to_char(txn_attempted_time, 'MM-DD-YYYY HH12:MI:SS AM') as txn_time, txn_attempted_type, response, response_code, response_reason_code, + response_reason_text, auth_code, avs_code, amount + from ezic_gateway_result_log + where '1'='1' [ad_dimensional_sql $dimensional] + [ad_order_by_from_sort_spec $orderby $table_def]" $table_def] Index: openacs-4/packages/ezic-gateway/www/admin/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/www/admin/index.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/www/admin/index.xql 5 Jan 2005 19:54:12 -0000 1.1 @@ -0,0 +1,32 @@ + + + + + + select p.instance_name + from apm_packages p, apm_package_versions v + where p.package_id = :package_id + and p.package_key = v.package_key + and v.enabled_p = 't' + + + + + + response_code='1' + + + + + + response_code='2' + + + + + + response_code='3' + + + + Index: openacs-4/packages/ezic-gateway/www/doc/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/www/doc/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/www/doc/index.adp 5 Jan 2005 19:54:13 -0000 1.1 @@ -0,0 +1,245 @@ + + @title@ + @signatory@ + + +
@context_bar;noquote@[ Administer ]
+
+ + @context_bar@ + + +

Description

+ +

The @package_name@ package implements the Payment Service + Contract for the EZIC on-line merchant + services. +

+ +

The @package_name@ is the intermediary between OpenACS packages + and the EZIC credit card acceptance services. This + gateway accepts calls to the Payment Service Contract operations, + forwards the information to the EZIC gateway and decodes the response + before returning the outcome back to the calling package while + keeping a log of all communication with EZIC. The log is + accessible from the @package_name@ administration. +

+ + +

Background

+ +

The ecommerce package + originally used online merchant credit-card payment fulfillment services provided by CyberCash. + Verisign bought Cybercash and merged it with their own PayflowPro service, leaving the + ecommerce package without a functioning credit card payment fulfillment service. +

+ +

Janine Sisk of furfly.net and Bart Teeuwisse + teamed together to produce a general purpose payment service contract + and to create the first implementations of the contract. Janine + developed the interface to PayflowPro the successor of CyberCash + while Bart created the gateway to Authorize.net. +

+ +

Berklee College Of Music + sponsored the creation of the Authorize.net package and its integration + with the ecommerce package. King Solar + sponsored the adaption of the Authorize.net Gateway to the @package_name@. +

+ +

Requirements

+ +

The @package_name@ requires the AOLserver + nsopenssl module to be installed. + Nsopenssl provides the ns_httpsget and ns_httpspost instructions to connect to the secure ADC server. + Aolserver 3.x requires nsopenssl version 2.x, Aolserver 4.x requires nsopenssl version 3.x. + The latest revision is available from Aolserver.com's + download area. +

+

+ Please follow the installation instructions included with the software. +

+

Oracle Admins: This release has been developed on PostgreSQL only. + The database queries appear to be compatible with Oracle, + however the files for creating the Oracle data-model and administrative reports have not been created. + Please report any problems to package maintainer, or the bugtracker at + OpenACS.org. You can also contribute + patches there, for example to update Oracle support. +

+

+ Note: The following is mentioned for your information only. No action is anticipated for these items. +

+

EZIC saves credit card numbers in their database, so that merchants do not need to. + Card numbers are then accessible via the transaction_id. + It is theoretically possible to upgrade this package with ecommerce to use the + Ecommerce package "SaveCreditCardDataP" parameter's feature while meeting + current credit card security requirements. +

+

+ Dqd_utils is not required or used. +

+

+ EZIC Gateway requires cardholder first and last name to be supplied separately for AVS. + OpenACS uses first_names and last_name fields for the user. The Ecommerce package data model + combines user's first_names and last_name as default value for card_name (ec_addresses.attn). + A 3 space delimiter separates the two values in the card_name field, so that gateway packages, + including this one, can split the field to separate names for AVS purposes. +

+

Configuration

+

The @package_name@ needs to be configured before it can connect + to EZIC.com and access your account with EZIC.com + Configuration is via @package_name@ + parameters. The package + has 8 parameters: +

+ +
    +
  1. + +

    CreditCardsAccepted

    + +

    A list of credit cards accepted by your EZIC.com + account. Calling applications can use this list or overwrite + it with their own list so that applications can choose to + accept only a subset of the cards your EZIC account + can handle.

    +
  2. +
  3. +

    test_request

    + +

    EZIC package test mode. When true, adds communication + send data to the aolserver log. Does *not* put + EZIC.com's gateway in transaction test mode. The default is + 'false'. EZIC response data is noted on the admin page. +

    +

    Note: For EZIC Transaction Test mode see EZIC.com :Account config :Credit cards - Optional Test Mode from the EZIC website Merchant access control pages. +

    + +
  4. +
  5. + +

    ezic_url

    + +

    The location (URL) of the EZIC.com Gateway. Unless you + received a different location from EZIC, there is no + need to change the default value.

    + +
  6. +
  7. + +

    referer_url

    + +

    The location (full URL formal) of your web site where the communication + with originates from. This URL will be used in the post header to EZIC. +

    +

    EZIC uses ip number filtering. Be sure to include the ip number + of your server in the appropriate EZIC.com security field. +

    + +
  8. +
  9. +

    ezic_login

    + +

    Your EZIC merchant or agent Account ID (not SiteID) +

    +
  10. +
  11. +

    ezic_sitetag

    + +

    Your EZIC merchant or agent Site Tag. This is optional if merchant + has only configured one site in the EZIC.com merchant access area. The + sitetag is defined in the EZIC ':Setup :Website config' menu area. +

    +
  12. +
  13. + +

    field_encapsulator

    + +

    The field encapsulation character in the Automated Direct + Connect (ADC) settings of EZIC.com. Currently, EZIC does not use + this feature, so leave it blank. The code is grandfathered into + this package from Authorize.net package, to make it easier to + adapt to this feature, should EZIC require it at some point. +

    + +
  14. +
  15. + +

    field_seperator

    + +

    The field seperator in Automated Direct Connect (ADC) + EZIC Direct Mode. This is the character that delimits (separates) + the elements in the response from EZIC.com. As of Jan. 2004, this + value is not changeable. Leave as is. Default is '&'. +

    + +
  16. +
+

Glossary

+
    +
  • + ADC - Automated Direct Connect, another way of stating EZIC Direct Mode +
  • +
  • + AVS - Address Verification System +
  • +
  • + package key - For this package: ezic-gateway +
  • +
+ +

API Reference

+ +

The Payment Service Contract explains the API to other + packages in detail.

+ +

Visit the EZIC + Direct Mode documentation for in-depth documentation of the + EZIC Direct Mode API that this package interfaces with. Be sure to review + the additional security measures available via the EZIC + merchant access control area and virtual terminal. +

+ +

Credits

+ +

The @package_name@ was adapted by + Torben Brosten for + King Solar from the + Authorize-Gateway Package, which was originally designed and written by + Bart Teeuwisse + for Berklee College Of + Music while working as a subcontractor for furfly.net. +

+

The @package_name@ 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 of + the License, or (at your option) any later version. +

+

The @package_name@ is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. +

+

A copy of the GNU General Public License is + included. If not write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA +

+ + + + + + + Index: openacs-4/packages/ezic-gateway/www/doc/index.css =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/www/doc/index.css,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/www/doc/index.css 5 Jan 2005 19:54:13 -0000 1.1 @@ -0,0 +1,5 @@ +p.note { + font-style: italic; + padding: 10; + background-color: lightgrey; +} Index: openacs-4/packages/ezic-gateway/www/doc/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/www/doc/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/www/doc/index.tcl 5 Jan 2005 19:54:13 -0000 1.1 @@ -0,0 +1,46 @@ +ad_page_contract { + + Index to documentation of the Authorize.net Gateway, an + implementation of the Payment Service Contract. + + @author Bart Teeuwisse + @modified-by Torben Brosten + @creation-date May 2002 + @modified-date Feb 2004 + +} { +} -properties { + title:onevalue + context_bar:onevalue +} + +# Authenticate the user + +set user_id [ad_maybe_redirect_for_registration] + +set package_name "EZIC Gateway" +set title "$package_name Package Documentation" +set package_url [apm_package_url_from_key "ezic-gateway"] +set package_id [apm_package_id_from_key "ezic-gateway"] + +# Check if the package has been mounted. + +set ezic_gateway_mounted [expr ![empty_string_p $package_url]] + +# Check for admin privileges + +set admin_p [ad_permission_p $package_id admin] + +# Check if the ecommerce and the shipping service contract packages +# are installed on the system. + +set ecommerce_installed [apm_package_installed_p ecommerce] +set payment_gateway_installed [apm_package_installed_p "payment-gateway"] + +# Set the context bar. + +set context_bar [ad_context_bar $package_name] + +# Set signatory for at the bottom of the page + +set signatory "torben@kappacorp.com" Index: openacs-4/packages/ezic-gateway/www/doc/license.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/www/doc/license.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/www/doc/license.adp 5 Jan 2005 19:54:13 -0000 1.1 @@ -0,0 +1,317 @@ + + @title@ + @signatory@ + @context_bar@ + + +

GNU General Public License

+ +

Version 2, June 1991

+ +
+    Copyright (C) 1989, 1991 Free Software Foundation, Inc.  
+    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+
+    Everyone is permitted to copy and distribute verbatim copies
+    of this license document, but changing it is not allowed.
+  
+ +

Preamble

+ +

The licenses for most software are designed to take away your + freedom to share and change it. By contrast, the GNU General + Public License is intended to guarantee your freedom to share and + change free software--to make sure the software is free for all + its users. This General Public License applies to most of the + Free Software Foundation's software and to any other program whose + authors commit to using it. (Some other Free Software Foundation + software is covered by the GNU Library General Public License + instead.) You can apply it to your programs, too.

+ +

When we speak of free software, we are referring to freedom, not + price. Our General Public Licenses are designed to make sure that + you have the freedom to distribute copies of free software (and + charge for this service if you wish), that you receive source code + or can get it if you want it, that you can change the software or + use pieces of it in new free programs; and that you know you can + do these things.

+ +

To protect your rights, we need to make restrictions that forbid + anyone to deny you these rights or to ask you to surrender the + rights. These restrictions translate to certain responsibilities + for you if you distribute copies of the software, or if you modify + it.

+ +

For example, if you distribute copies of such a program, whether + gratis or for a fee, you must give the recipients all the rights + that you have. You must make sure that they, too, receive or can + get the source code. And you must show them these terms so they + know their rights.

+ +

We protect your rights with two steps: (1) copyright the + software, and (2) offer you this license which gives you legal + permission to copy, distribute and/or modify the software.

+ +

Also, for each author's protection and ours, we want to make + certain that everyone understands that there is no warranty for + this free software. If the software is modified by someone else + and passed on, we want its recipients to know that what they have + is not the original, so that any problems introduced by others + will not reflect on the original authors' reputations.

+ +

Finally, any free program is threatened constantly by software + patents. We wish to avoid the danger that redistributors of a + free program will individually obtain patent licenses, in effect + making the program proprietary. To prevent this, we have made it + clear that any patent must be licensed for everyone's free use or + not licensed at all.

+ +

The precise terms and conditions for copying, distribution and + modification follow.

+ +

Terms and conditions for copying, distribution and modification

+ +

0. This License applies to any program or other + work which contains a notice placed by the copyright holder saying + it may be distributed under the terms of this General Public + License. The "Program", below, refers to any such program or + work, and a "work based on the Program" means either the Program + or any derivative work under copyright law: that is to say, a work + containing the Program or a portion of it, either verbatim or with + modifications and/or translated into another language. + (Hereinafter, translation is included without limitation in the + term "modification".) Each licensee is addressed as "you".

+ +

Activities other than copying, distribution and modification are + not covered by this License; they are outside its scope. The act + of running the Program is not restricted, and the output from the + Program is covered only if its contents constitute a work based on + the Program (independent of having been made by running the + Program). Whether that is true depends on what the Program does.

+ +

1. You may copy and distribute verbatim copies + of the Program's source code as you receive it, in any medium, + provided that you conspicuously and appropriately publish on each + copy an appropriate copyright notice and disclaimer of warranty; + keep intact all the notices that refer to this License and to the + absence of any warranty; and give any other recipients of the + Program a copy of this License along with the Program.

+ + +

You may charge a fee for the physical act of transferring a copy, + and you may at your option offer warranty protection in exchange + for a fee.

+ +

2. You may modify your copy or copies of the + Program or any portion of it, thus forming a work based on the + Program, and copy and distribute such modifications or work under + the terms of Section 1 above, provided that you also meet all of + these conditions:

+ +
    + +
  • a) You must cause the modified files to carry + prominent notices stating that you changed the files and the + date of any change.

  • + +
  • b) You must cause any work that you + distribute or publish, that in whole or in part contains or is + derived from the Program or any part thereof, to be licensed as + a whole at no charge to all third parties under the terms of + this License.

  • + +
  • c) If the modified program normally reads + commands interactively when run, you must cause it, when started + running for such interactive use in the most ordinary way, to + print or display an announcement including an appropriate + copyright notice and a notice that there is no warranty (or + else, saying that you provide a warranty) and that users may + redistribute the program under these conditions, and telling the + user how to view a copy of this License. (Exception: if the + Program itself is interactive but does not normally print such + an announcement, your work based on the Program is not required + to print an announcement.)

  • +
+ +

These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the + Program, and can be reasonably considered independent and separate + works in themselves, then this License, and its terms, do not + apply to those sections when you distribute them as separate + works. But when you distribute the same sections as part of a + whole which is a work based on the Program, the distribution of + the whole must be on the terms of this License, whose permissions + for other licensees extend to the entire whole, and thus to each + and every part regardless of who wrote it.

+ +

Thus, it is not the intent of this section to claim rights or + contest your rights to work written entirely by you; rather, the + intent is to exercise the right to control the distribution of + derivative or collective works based on the Program.

+ +

In addition, mere aggregation of another work not based on the + Program with the Program (or with a work based on the Program) on + a volume of a storage or distribution medium does not bring the + other work under the scope of this License.

+ +

3. You may copy and distribute the Program (or + a work based on it, under Section 2) in object code or executable + form under the terms of Sections 1 and 2 above provided that you + also do one of the following:

+ +
    + +
  • a) Accompany it with the complete + corresponding machine-readable source code, which must be + distributed under the terms of Sections 1 and 2 above on a + medium customarily used for software interchange; or,

  • + +
  • b) Accompany it with a written offer, + valid for at least three years, to give any third party, for a + charge no more than your cost of physically performing source + distribution, a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Sections 1 and 2 above on a medium customarily used for software + interchange; or,

  • + +
  • c) Accompany it with the information you + received as to the offer to distribute corresponding source + code. (This alternative is allowed only for noncommercial + distribution and only if you received the program in object code + or executable form with such an offer, in accord with Subsection + b above.)

  • +
+ +

The source code for a work means the preferred form of the work + for making modifications to it. For an executable work, complete + source code means all the source code for all modules it contains, + plus any associated interface definition files, plus the scripts + used to control compilation and installation of the executable. + However, as a special exception, the source code distributed need + not include anything that is normally distributed (in either + source or binary form) with the major components (compiler, + kernel, and so on) of the operating system on which the executable + runs, unless that component itself accompanies the executable.

+ +

If distribution of executable or object code is made by offering + access to copy from a designated place, then offering equivalent + access to copy the source code from the same place counts as + distribution of the source code, even though third parties are not + compelled to copy the source along with the object code.

+ +

4. You may not copy, modify, sublicense, or + distribute the Program except as expressly provided under this + License. Any attempt otherwise to copy, modify, sublicense or + distribute the Program is void, and will automatically terminate + your rights under this License. However, parties who have + received copies, or rights, from you under this License will not + have their licenses terminated so long as such parties remain in + full compliance.

+ +

5. You are not required to accept this + License, since you have not signed it. However, nothing else + grants you permission to modify or distribute the Program or its + derivative works. These actions are prohibited by law if you do + not accept this License. Therefore, by modifying or distributing + the Program (or any work based on the Program), you indicate your + acceptance of this License to do so, and all its terms and + conditions for copying, distributing or modifying the Program or + works based on it.

+ +

6. Each time you redistribute the Program (or any + work based on the Program), the recipient automatically receives a + license from the original licensor to copy, distribute or modify + the Program subject to these terms and conditions. You may not + impose any further restrictions on the recipients' exercise of the + rights granted herein. You are not responsible for enforcing + compliance by third parties to this License.

+ +

7. If, as a consequence of a court judgment or + allegation of patent infringement or for any other reason (not + limited to patent issues), conditions are imposed on you (whether + by court order, agreement or otherwise) that contradict the + conditions of this License, they do not excuse you from the + conditions of this License. If you cannot distribute so as to + satisfy simultaneously your obligations under this License and any + other pertinent obligations, then as a consequence you may not + distribute the Program at all. For example, if a patent license + would not permit royalty-free redistribution of the Program by all + those who receive copies directly or indirectly through you, then + the only way you could satisfy both it and this License would be + to refrain entirely from distribution of the Program.

+ +

If any portion of this section is held invalid or unenforceable + under any particular circumstance, the balance of the section is + intended to apply and the section as a whole is intended to apply + in other circumstances.

+ +

It is not the purpose of this section to induce you to infringe + any patents or other property right claims or to contest validity + of any such claims; this section has the sole purpose of + protecting the integrity of the free software distribution system, + which is implemented by public license practices. Many people + have made generous contributions to the wide range of software + distributed through that system in reliance on consistent + application of that system; it is up to the author/donor to decide + if he or she is willing to distribute software through any other + system and a licensee cannot impose that choice.

+ +

This section is intended to make thoroughly clear what is + believed to be a consequence of the rest of this License.

+ +

8. If the distribution and/or use of the Program + is restricted in certain countries either by patents or by + copyrighted interfaces, the original copyright holder who places + the Program under this License may add an explicit geographical + distribution limitation excluding those countries, so that + distribution is permitted only in or among countries not thus + excluded. In such case, this License incorporates the limitation + as if written in the body of this License.

+ +

9. The Free Software Foundation may publish + revised and/or new versions of the General Public License from + time to time. Such new versions will be similar in spirit to the + present version, but may differ in detail to address new problems + or concerns.

+ +

Each version is given a distinguishing version number. If the + Program specifies a version number of this License which applies + to it and "any later version", you have the option of following + the terms and conditions either of that version or of any later + version published by the Free Software Foundation. If the Program + does not specify a version number of this License, you may choose + any version ever published by the Free Software Foundation.

+ +

10. If you wish to incorporate parts of the + Program into other free programs whose distribution conditions are + different, write to the author to ask for permission. For + software which is copyrighted by the Free Software Foundation, + write to the Free Software Foundation; we sometimes make + exceptions for this. Our decision will be guided by the two goals + of preserving the free status of all derivatives of our free + software and of promoting the sharing and reuse of software + generally.

+ +

NO WARRANTY

+ +

11. BECAUSE THE PROGRAM IS LICENSED FREE OF + CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT + PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN + WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE + PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR + IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE + RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. + SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL + NECESSARY SERVICING, REPAIR OR CORRECTION.

+ +

12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW + OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER + PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED + ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, + SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE + USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO + LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED + BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE + WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS + BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

Index: openacs-4/packages/ezic-gateway/www/doc/license.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ezic-gateway/www/doc/license.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ezic-gateway/www/doc/license.tcl 5 Jan 2005 19:54:13 -0000 1.1 @@ -0,0 +1,30 @@ +ad_page_contract { + + License information of the Authorize.net Gateway, an + implementation of the Payment Service Contract. + + @author Bart Teeuwisse + @modified-by Torben Brosten + @creation-date May 2002 + @modified-date Feb 2004 + +} { +} -properties { + title:onevalue + context_bar:onevalue +} + +# Authenticate the user + +set user_id [ad_maybe_redirect_for_registration] + +set package_name "Authorize.net Gateway" +set title "$package_name License" + +# Set the context bar. + +set context_bar [ad_context_bar [list . $package_name] License] + +# Set signatory for at the bottom of the page + +set signatory "torben@kappacorp.com"