Index: openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs.tcl,v diff -u -r1.12 -r1.13 --- openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs.tcl 4 Sep 2008 12:24:06 -0000 1.12 +++ openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs.tcl 8 Sep 2008 10:35:13 -0000 1.13 @@ -53,10 +53,10 @@ # PaymentGateway. if {[empty_string_p $payment_gateway] || ![acs_sc_binding_exists_p "PaymentGateway" $payment_gateway]} { - ns_log Warning "ec_creditcard_authorization (54): payment gateway not bound to ecommerce package." - set outcome(response_code) "failure" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] + ns_log Warning "ec_creditcard_authorization (54): payment gateway not bound to ecommerce package." + set outcome(response_code) "failure" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } # Authorize the entire order when the transaction_id is null, @@ -66,55 +66,55 @@ # for gift certificates). if { [empty_string_p $transaction_id] } { - db_1row order_data_select " - select ec_order_cost(:order_id) as total_amount, - creditcard_id from ec_orders - where order_id = :order_id" + db_1row order_data_select " + select ec_order_cost(:order_id) as total_amount, + creditcard_id from ec_orders + where order_id = :order_id" } else { - db_1row transaction_data_select " - select transaction_amount as total_amount, creditcard_id - from ec_financial_transactions - where transaction_id = :transaction_id" + db_1row transaction_data_select " + select transaction_amount as total_amount, creditcard_id + from ec_financial_transactions + where transaction_id = :transaction_id" } # The order amount is 0 (zero) and there is thus no need # to contact the payment gateway. Record an instant # success. if {$total_amount == 0} { - set outcome(response_code) "authorized" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] + set outcome(response_code) "authorized" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } # Lookup the credit card for the transaction. Record an # invalid_input error if there isn't one. if {![db_0or1row creditcard_data_select " - select c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, - c.creditcard_type, a.attn as card_name, - a.zip_code as billing_zip, - a.line1 as billing_address, - a.city as billing_city, - coalesce(a.usps_abbrev, a.full_state_name) as billing_state, - a.country_code as billing_country - from ec_creditcards c, persons p, ec_addresses a - where c.user_id=p.person_id - and c.creditcard_id = :creditcard_id - and c.billing_address = a.address_id"]} { - set outcome(response_code) "invalid_input" - set outcome(transaction_id) "$transaction_id" - ns_log Error "ec_creditcard_authorization (105): no creditcard for transaction_id $transaction_id" - return [array get outcome] + select c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, + c.creditcard_type, a.attn as card_name, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_creditcards c, persons p, ec_addresses a + where c.user_id=p.person_id + and c.creditcard_id = :creditcard_id + and c.billing_address = a.address_id"]} { + set outcome(response_code) "invalid_input" + set outcome(transaction_id) "$transaction_id" + ns_log Error "ec_creditcard_authorization (105): no creditcard for transaction_id $transaction_id" + return [array get outcome] } # Generate a transaction_id if none has been provided. if { [empty_string_p $transaction_id] } { - set transaction_id [db_string latest_transaction_select " - select max(transaction_id) - from ec_financial_transactions - where order_id = :order_id"] + set transaction_id [db_string latest_transaction_select " + select max(transaction_id) + from ec_financial_transactions + where order_id = :order_id"] ns_log Notice "ec_creditcard_authorization creating transaction_id ${transaction_id}" } @@ -131,27 +131,27 @@ # Connect to the payment gateway to authorize the transaction. array set response [acs_sc_call "PaymentGateway" "Authorize" \ - [list $transaction_id \ - $total_amount \ - $card_type \ - $card_number \ - $card_exp_month \ - $card_exp_year \ + [list $transaction_id \ + $total_amount \ + $card_type \ + $card_number \ + $card_exp_month \ + $card_exp_year \ $card_code \ - $card_name \ - $billing_address \ - $billing_city \ - $billing_state \ - $billing_zip \ - $billing_country] \ - $payment_gateway] + $card_name \ + $billing_address \ + $billing_city \ + $billing_state \ + $billing_zip \ + $billing_country] \ + $payment_gateway] # Extract response_code, reason and the gateway transaction id # from the response. The response_code values are defined in # payment-gateway/tcl/payment-gateway-init.tcl. The reason is a # human readable description of the response and the # transaction id is the ID as returned by the payment gateway. - + set response_code $response(response_code) set reason $response(reason) set pgw_transaction_id $response(transaction_id) @@ -160,63 +160,63 @@ # Interpret the response_code. switch -exact $response_code { - - "failure" - - "not_supported" - - "not_implemented" { - - # The payment gateway rejected to authorize the - # transaction. Or is not capable of authorizing - # transactions. - - set outcome(response_code) "failed_authorization" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] - } - - "failure-retry" { - - # If the response_code is failure-retry, it means there was a - # temporary failure that can be retried. The order will be - # retried the next time the scheduled procedure - # ec_sweep_for_payment_zombies is run. - set outcome(response_code) "no_recommendation" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] - } - - "success" { - - # The payment gateway authorized the transaction. - - db_dml update_transaction_id " - update ec_financial_transactions - set transaction_id = :pgw_transaction_id - where transaction_id = :transaction_id" - - set outcome(response_code) "authorized" - set outcome(transaction_id) "$pgw_transaction_id" - return [array get outcome] - } - - default { - - # Unknown response_code, fail the authorization to be on - # the safe side. - - set outcome(response_code) "failured_authorization" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] - } + "failure" - + "not_supported" - + "not_implemented" { + + # The payment gateway rejected to authorize the + # transaction. Or is not capable of authorizing + # transactions. + + set outcome(response_code) "failed_authorization" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } + + "failure-retry" { + + # If the response_code is failure-retry, it means there was a + # temporary failure that can be retried. The order will be + # retried the next time the scheduled procedure + # ec_sweep_for_payment_zombies is run. + + set outcome(response_code) "no_recommendation" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } + + "success" { + + # The payment gateway authorized the transaction. + + db_dml update_transaction_id " + update ec_financial_transactions + set transaction_id = :pgw_transaction_id + where transaction_id = :transaction_id" + + set outcome(response_code) "authorized" + set outcome(transaction_id) "$pgw_transaction_id" + return [array get outcome] + } + + default { + + # Unknown response_code, fail the authorization to be on + # the safe side. + + set outcome(response_code) "failured_authorization" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } } } ad_proc -public ec_creditcard_marking { transaction_id {card_code ""} } { - + Connect to the payment gateway to charge a previously authorized credit card for a transaction. This marks the transaction for settlement by the credit card gateway at the end of the day (or @@ -261,9 +261,9 @@ # PaymentGateway. if {[empty_string_p $payment_gateway] || ![acs_sc_binding_exists_p "PaymentGateway" $payment_gateway]} { - set outcome(response_code) "failure" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] + set outcome(response_code) "failure" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } # Retrieve the transaction amount from the database. NOTE The @@ -272,35 +272,35 @@ # transaction. db_1row transaction_select " - select f.transaction_amount, f.transaction_id, c.creditcard_type, a.attn card_name, - c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, + select f.transaction_amount, f.transaction_id, c.creditcard_type, a.attn card_name, + c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, a.zip_code as billing_zip, a.line1 as billing_address, a.city as billing_city, coalesce(a.usps_abbrev, a.full_state_name) as billing_state, a.country_code as billing_country - from ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a - where transaction_id = :transaction_id - and f.creditcard_id = c.creditcard_id - and c.user_id = p.person_id - and c.billing_address = a.address_id" + from ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a + where transaction_id = :transaction_id + and f.creditcard_id = c.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_id" # Fail the post authorization no transaction amount has been retrieved. if { [empty_string_p $transaction_amount] } { - set outcome(response_code) "invalid_input" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] + set outcome(response_code) "invalid_input" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } # The order amount is 0 (zero) and there is thus no need # to contact the payment gateway. Record an instant # success. if {$transaction_amount == 0 } { - set outcome(response_code) "success" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] + set outcome(response_code) "success" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } # Convert the one digit creditcard abbreviation to the @@ -314,20 +314,20 @@ # Connect to the payment gateway to authorize the transaction. array set response [acs_sc_call "PaymentGateway" "ChargeCard" \ - [list $transaction_id \ - $transaction_amount \ - $card_type \ - $card_number \ - $card_exp_month \ - $card_exp_year \ + [list $transaction_id \ + $transaction_amount \ + $card_type \ + $card_number \ + $card_exp_month \ + $card_exp_year \ $card_code \ - $card_name \ - $billing_address \ - $billing_city \ - $billing_state \ - $billing_zip \ - $billing_country] \ - $payment_gateway] + $card_name \ + $billing_address \ + $billing_city \ + $billing_state \ + $billing_zip \ + $billing_country] \ + $payment_gateway] # Extract response_code, reason and the gateway transaction id # from the response. The response_code values are defined in @@ -342,48 +342,48 @@ # Interpret the response_code. switch -exact $response_code { - - "failure" - - default { - - # The payment gateway rejected to post authorize the - # transaction or returned an unknown response_code, fail the - # post authorization to be on the safe side. - - set outcome(response_code) "failure" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] - } - - "failure-retry" - - "not_supported" - - "not_implemented" { - - # If the response_code is failure-retry, it means there was a - # temporary failure that can be retried. The order will be - # retried the next time the scheduled procedure - # ec_sweep_for_payment_zombies is run. Treat not_supported and - # not_implemented responses the same. - set outcome(response_code) "unknown" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] - } + "failure" - + default { - "success" { - - # The payment gateway approved the transaction. - - if { ![empty_string_p $pgw_transaction_id] } { - db_dml update_transaction_id " - update ec_financial_transactions - set transaction_id = :pgw_transaction_id - where transaction_id = :transaction_id" - } - set outcome(response_code) "success" - set outcome(transaction_id) "$pgw_transaction_id" - return [array get outcome] - } + # The payment gateway rejected to post authorize the + # transaction or returned an unknown response_code, fail the + # post authorization to be on the safe side. + + set outcome(response_code) "failure" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } + + "failure-retry" - + "not_supported" - + "not_implemented" { + + # If the response_code is failure-retry, it means there was a + # temporary failure that can be retried. The order will be + # retried the next time the scheduled procedure + # ec_sweep_for_payment_zombies is run. Treat not_supported and + # not_implemented responses the same. + + set outcome(response_code) "unknown" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } + + "success" { + + # The payment gateway approved the transaction. + + if { ![empty_string_p $pgw_transaction_id] } { + db_dml update_transaction_id " + update ec_financial_transactions + set transaction_id = :pgw_transaction_id + where transaction_id = :transaction_id" + } + set outcome(response_code) "success" + set outcome(transaction_id) "$pgw_transaction_id" + return [array get outcome] + } } } @@ -434,9 +434,9 @@ # PaymentGateway. if {[empty_string_p $payment_gateway] || ![acs_sc_binding_exists_p "PaymentGateway" $payment_gateway]} { - set outcome(response_code) "failure" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] + set outcome(response_code) "failure" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } # Retrieve the transaction amount and the credit card information @@ -447,31 +447,31 @@ if {![db_0or1row transaction_info_select " select t.refunded_transaction_id, t.transaction_amount, - c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, - a.attn as card_name, - a.zip_code as billing_zip, - a.line1 as billing_address, - a.city as billing_city, - coalesce(a.usps_abbrev, a.full_state_name) as billing_state, - a.country_code as billing_country + c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, + a.attn as card_name, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country from ec_financial_transactions t, ec_creditcards c, persons p, ec_addresses a where t.transaction_id = :transaction_id and c.creditcard_id = t.creditcard_id - and c.user_id = p.person_id - and c.billing_address = a.address_id"]} { - set outcome(response_code) "invalid_input" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] + and c.user_id = p.person_id + and c.billing_address = a.address_id"]} { + set outcome(response_code) "invalid_input" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } # The order amount is 0 (zero) and there is thus no need # to contact the payment gateway. Record an instant # success. - + if { $transaction_amount == 0 } { - set outcome(response_code) "success" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] + set outcome(response_code) "success" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } # Convert the one digit creditcard abbreviation to the @@ -485,20 +485,20 @@ # Connect to the payment gateway to authorize the transaction. array set response [acs_sc_call "PaymentGateway" "Return" \ - [list $refunded_transaction_id \ - $transaction_amount \ - $card_type \ - $card_number \ - $card_exp_month \ - $card_exp_year \ + [list $refunded_transaction_id \ + $transaction_amount \ + $card_type \ + $card_number \ + $card_exp_month \ + $card_exp_year \ $card_code \ - $card_name \ - $billing_address \ - $billing_city \ - $billing_state \ - $billing_zip \ - $billing_country] \ - $payment_gateway] + $card_name \ + $billing_address \ + $billing_city \ + $billing_state \ + $billing_zip \ + $billing_country] \ + $payment_gateway] # Extract response_code, reason and the gateway transaction id # from the response. The response_code values are defined in @@ -514,51 +514,51 @@ switch -exact $response_code { - "failure" - - default { - - # The payment gateway rejected to refund the transaction or - # returned an unknown response_code. Fail the post - # authorization to be on the safe side. - - db_dml transaction_failure_update " - update ec_financial_transactions - set failed_p = 't' - where transaction_id = :transaction_id" - - set outcome(response_code) "failure" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] - } - - "failure-retry" - - "not_supported" - - "not_implemented" { - - # If the response_code is failure-retry, it means there was a - # temporary failure that can be retried. The order will be - # retried the next time the scheduled procedure - # ec_sweep_for_payment_zombies is run. Treat not_supported and - # not_implemented responses the same. - - set outcome(response_code) "unknown" - set outcome(transaction_id) "$transaction_id" - return [array get outcome] - } - - "success" { - - # The payment gateway authorized the transaction. - - db_dml transaction_success_update " - update ec_financial_transactions - set transaction_id = :pgw_transaction_id, refunded_date = sysdate - where transaction_id = :transaction_id" - - set outcome(response_code) "success" - set outcome(transaction_id) "$pgw_transaction_id" - return [array get outcome] - } + "failure" - + default { + + # The payment gateway rejected to refund the transaction or + # returned an unknown response_code. Fail the post + # authorization to be on the safe side. + + db_dml transaction_failure_update " + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id" + + set outcome(response_code) "failure" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } + + "failure-retry" - + "not_supported" - + "not_implemented" { + + # If the response_code is failure-retry, it means there was a + # temporary failure that can be retried. The order will be + # retried the next time the scheduled procedure + # ec_sweep_for_payment_zombies is run. Treat not_supported and + # not_implemented responses the same. + + set outcome(response_code) "unknown" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } + + "success" { + + # The payment gateway authorized the transaction. + + db_dml transaction_success_update " + update ec_financial_transactions + set transaction_id = :pgw_transaction_id, refunded_date = sysdate + where transaction_id = :transaction_id" + + set outcome(response_code) "success" + set outcome(transaction_id) "$pgw_transaction_id" + return [array get outcome] + } } } @@ -567,7 +567,7 @@ creditcard_type {creditcard_code ""} } { - + Prechecks credit card numbers. If you're going to accept cards other than MasterCard, Visa, or American Express, you'll have to modify this proc to recognize them. It should be easy; just @@ -592,104 +592,104 @@ set card_code_required [parameter::get -package_id [ec_id] -parameter PaymentCardCodeRequired -default 0] if {![empty_string_p $creditcard_type]} { - switch -exact $creditcard_type { - - "m" { - if {[string index $creditcard_number 0] != 5} { - incr exception_count - append exception_text "