From dc30ecccbefe6b54ee060ca10205336b0cfe1de0 Mon Sep 17 00:00:00 2001 From: Martin Kamerbeek Date: Mon, 26 May 2008 21:31:48 +0000 Subject: [PATCH] Recurring payment stuff fixes, forgot ITransact.pm in last commit. --- lib/WebGUI/Asset/Sku/Subscription.pm | 26 ++++++ lib/WebGUI/Shop/PayDriver.pm | 17 ++-- lib/WebGUI/Shop/PayDriver/ITransact.pm | 109 ++++++++++++++++--------- 3 files changed, 109 insertions(+), 43 deletions(-) diff --git a/lib/WebGUI/Asset/Sku/Subscription.pm b/lib/WebGUI/Asset/Sku/Subscription.pm index 30fbfa9be..e34de4165 100644 --- a/lib/WebGUI/Asset/Sku/Subscription.pm +++ b/lib/WebGUI/Asset/Sku/Subscription.pm @@ -383,6 +383,32 @@ sub getPrice { #------------------------------------------------------------------- +=head2 getRecurInterval + +Returns the duration of this subscription in a format used by the commerce system. + +=cut + +sub getRecurInterval { + my $self = shift; + + return $self->get('duration'); +} + +#------------------------------------------------------------------- + +=head2 isRecurring + +Tells the commerce system this Sku is recurring. + +=cut + +sub isRecurring { + return 1; +} + +#------------------------------------------------------------------- + =head2 onCompletePurchase Applies the first term of the subscription. This method is called when the payment is successful. diff --git a/lib/WebGUI/Shop/PayDriver.pm b/lib/WebGUI/Shop/PayDriver.pm index a2ab6fc63..47018a5fd 100644 --- a/lib/WebGUI/Shop/PayDriver.pm +++ b/lib/WebGUI/Shop/PayDriver.pm @@ -519,12 +519,19 @@ A reference to a WebGUI::Shop::Address object that should be attached as payment sub processTransaction { my ($self, $paymentAddress) = @_; + my $cart = $self->getCart; - my $transaction = WebGUI::Shop::Transaction->create($self->session,{ - paymentMethod => $self, - paymentAddress => $paymentAddress, - cart => $cart, - }); + + # Setup tranasction properties + my $transactionProperties; + $transactionProperties->{ paymentMethod } = $self; + $transactionProperties->{ cart } = $cart; + $transactionProperties->{ paymentAddress } = $paymentAddress if defined $paymentAddress; + + # Create a transaction... + my $transaction = WebGUI::Shop::Transaction->create( $self->session, $transactionProperties ); + + # And handle the payment for it my ($success, $transactionCode, $statusCode, $statusMessage) = $self->processPayment( $transaction ); if ($success) { $transaction->completePurchase($transactionCode, $statusCode, $statusMessage); diff --git a/lib/WebGUI/Shop/PayDriver/ITransact.pm b/lib/WebGUI/Shop/PayDriver/ITransact.pm index a92c4515e..cc3acea86 100644 --- a/lib/WebGUI/Shop/PayDriver/ITransact.pm +++ b/lib/WebGUI/Shop/PayDriver/ITransact.pm @@ -2,34 +2,10 @@ package WebGUI::Shop::PayDriver::ITransact; use strict; use XML::Simple; +use Data::Dumper; use base qw/WebGUI::Shop::PayDriver/; -sub _monthYear { - my $session = shift; - my $form = $session->form; - - tie my %months, "Tie::IxHash"; - tie my %years, "Tie::IxHash"; - %months = map { sprintf( '%02d', $_ ) => sprintf( '%02d', $_ ) } 1 .. 12; - %years = map { $_ => $_ } 2004 .. 2099; - - my $monthYear = - WebGUI::Form::selectBox( $session, { - name => 'expMonth', - options => \%months, - value => [ $form->process("expMonth") ] - }) - . " / " - . WebGUI::Form::selectBox( $session, { - name => 'expYear', - options => \%years, - value => [ $form->process("expYear") ] - }); - - return $monthYear; -} - #------------------------------------------------------------------- sub _generateCancelRecurXml { my $self = shift; @@ -63,6 +39,52 @@ sub _generateCancelRecurXml { return $xml; } +#------------------------------------------------------------------- +sub _monthYear { + my $session = shift; + my $form = $session->form; + + tie my %months, "Tie::IxHash"; + tie my %years, "Tie::IxHash"; + %months = map { sprintf( '%02d', $_ ) => sprintf( '%02d', $_ ) } 1 .. 12; + %years = map { $_ => $_ } 2004 .. 2099; + + my $monthYear = + WebGUI::Form::selectBox( $session, { + name => 'expMonth', + options => \%months, + value => [ $form->process("expMonth") ] + }) + . " / " + . WebGUI::Form::selectBox( $session, { + name => 'expYear', + options => \%years, + value => [ $form->process("expYear") ] + }); + + return $monthYear; +} + +#------------------------------------------------------------------- +sub _resolveRecurRecipe { + my $self = shift; + my $duration = shift; + + my %resolve = ( + Weekly => 'weekly', + BiWeekly => 'biweekly', + FourWeekly => 'fourweekly', + Monthly => 'monthly', + Quarterly => 'quarterly', + HalfYearly => 'halfyearly', + Yearly => 'yearly', + ); + + # TODO: Throw exception + return $resolve{ $duration }; +} + + #------------------------------------------------------------------- =head2 doXmlRequest ( xml [ isAdministrative ] ) @@ -264,24 +286,23 @@ sub _generatePaymentRequestXML { # Since recur recipes are based on intervals defined in days, the first term will payed NOW. Since the # subscription start NOW too, we never need an initial amount for recurring payments. if ( $sku->isRecurring ) { - $recurringData->{ RecurRecipe } = $self->resolveRecurRecipe( $sku->getRecurInterval ); + $recurringData->{ RecurRecipe } = $self->_resolveRecurRecipe( $sku->getRecurInterval ); $recurringData->{ RecurReps } = 99999; $recurringData->{ RecurTotal } = $item->get('price') + $transaction->get('taxes') + $transaction->get('shippingPrice'); $recurringData->{ RecurDesc } = $item->get('configuredTitle'); } - else { +# else { push @{ $orderItems->{ Item } }, { Description => $item->get('configuredTitle'), Cost => $item->get('price'), Qty => $item->get('quantity'), } - } +# } } # taxes, shipping, etc my $i18n = WebGUI::International->new($session, "Shop"); - #### TODO: Don't add this if the transaction is recurring if ( $transaction->get('taxes') > 0 ) { push @{ $orderItems->{ Item } }, { Description => $i18n->get('taxes'), @@ -289,7 +310,6 @@ sub _generatePaymentRequestXML { Qty => 1, }; } - #### TODO: Don't add this if the transaction is recurring if ($transaction->get('shippingPrice') > 0) { push @{ $orderItems->{ Item } }, { Description => $i18n->get('shipping'), @@ -316,7 +336,7 @@ sub _generatePaymentRequestXML { $transactionData->{ HomePage } = $self->session->setting->get("companyURL"); $transactionData->{ RecurringData } = $recurringData if $recurringData; $transactionData->{ EmailText } = $emailText if $emailText; - $transactionData->{ OrderItems } = $orderItems; + $transactionData->{ OrderItems } = $orderItems if $orderItems; # --- The XML structure --- my $xmlStructure = { @@ -407,6 +427,17 @@ sub processCredentials { return \@error; } +#------------------------------------------------------------------- + +=head2 handlesRecurring + +Tells the commerce system that this payment plugin can handle recurring payments. + +=cut + +sub handlesRecurring { + return 1; +} #------------------------------------------------------------------- sub processPayment { @@ -422,7 +453,7 @@ sub processPayment { my $userAgent = LWP::UserAgent->new; $userAgent->env_proxy; $userAgent->agent("WebGUI "); - + # Create a request and stuff the xml in it $session->errorHandler->info('Starting request'); my $xmlTransactionScript = 'https://secure.paymentclearing.com/cgi-bin/rc/xmltrans.cgi'; @@ -460,7 +491,7 @@ sub processPayment { my $gatewayCode = $transactionData->{ XID }; my $isSuccess = $status eq 'OK'; - return ( $isSuccess, $gatewayCode, $status, "$errorMessage Category: $errorCategory" ); + return ( $isSuccess, $gatewayCode, $status, "" ); } } else { # Connection Error @@ -477,10 +508,10 @@ sub www_processRecurringTransactionPostback { my $form = $session->form; # Get posted data of interest - my $originatingXid = $form->process( 'orig_xid' ); - my $status = $form->process( 'status' ); - my $xid = $form->process( 'xid' ); - my $errorMessage = $form->process( 'error_message' ); + my $originatingXid = $form->process( 'orig_xid' ); + my $status = $form->process( 'status' ); + my $xid = $form->process( 'xid' ); + my $errorMessage = $form->process( 'error_message' ); # Fetch the original transaction my $baseTransaction = WebGUI::Shop::Transaction->newByGatewayId( $session, $originatingXid, $self->getId ); @@ -499,6 +530,8 @@ sub www_processRecurringTransactionPostback { # The term has not been payed succesfully $transaction->denyPurchase( $xid, $status, $errorMessage ); } + + return undef; } #------------------------------------------------------------------- @@ -588,7 +621,7 @@ sub www_pay { # Check whether the user filled in the checkout form and process those. my $credentialsErrors = $self->processCredentials; - + # Go back to checkout form if credentials are not ok return $self->www_getCredentials( $credentialsErrors ) if $credentialsErrors;