From 31729dc14af6a5a27e818c3d31cf37a64c860aa9 Mon Sep 17 00:00:00 2001 From: JT Smith Date: Mon, 24 Mar 2008 18:27:33 +0000 Subject: [PATCH] add payment processing interface --- lib/WebGUI/Exception.pm | 4 + lib/WebGUI/Shop/Admin.pm | 14 ++++ lib/WebGUI/Shop/PayDriver.pm | 107 +++++++++++++++++++++++++-- lib/WebGUI/Shop/PayDriver/Cash.pm | 6 ++ lib/WebGUI/Shop/Transaction.pm | 9 ++- lib/WebGUI/i18n/English/PayDriver.pm | 60 ++++++++++++--- lib/WebGUI/i18n/English/Shop.pm | 24 ++++++ 7 files changed, 202 insertions(+), 22 deletions(-) diff --git a/lib/WebGUI/Exception.pm b/lib/WebGUI/Exception.pm index 61392aa3b..078bb2a5c 100644 --- a/lib/WebGUI/Exception.pm +++ b/lib/WebGUI/Exception.pm @@ -20,6 +20,10 @@ use Exception::Class ( 'WebGUI::Error' => { description => "A general error occured.", }, + 'WebGUI::Error::OverrideMe' => { + isa => 'WebGUI::Error', + description => 'This method should be overridden by subclasses.', + }, 'WebGUI::Error::InvalidObject' => { isa => 'WebGUI::Error::InvalidParam', description => "Expected to get a reference to an object type that wasn't gotten.", diff --git a/lib/WebGUI/Shop/Admin.pm b/lib/WebGUI/Shop/Admin.pm index e1a4a9596..e227e7213 100644 --- a/lib/WebGUI/Shop/Admin.pm +++ b/lib/WebGUI/Shop/Admin.pm @@ -140,6 +140,20 @@ sub www_editSettings { label => $i18n->get("edit address template"), hoverHelp => $i18n->get("edit address template help"), ); + $form->template( + name => "myPurchasesTemplateId", + value => $setting->get("myPurchasesTemplateId"), + namespace => "Shop/MyPurchases", + label => $i18n->get("my purchases template"), + hoverHelp => $i18n->get("my purchases template help"), + ); + $form->template( + name => "myPurchasesDetailTemplateId", + value => $setting->get("myPurchasesDetailTemplateId"), + namespace => "Shop/MyPurchases/Detail", + label => $i18n->get("my purchases detail template"), + hoverHelp => $i18n->get("my purchases detail template help"), + ); $form->submit; return $ac->render($form->print, $i18n->get("shop settings")); } diff --git a/lib/WebGUI/Shop/PayDriver.pm b/lib/WebGUI/Shop/PayDriver.pm index b5e88fda4..5fee6f4a0 100644 --- a/lib/WebGUI/Shop/PayDriver.pm +++ b/lib/WebGUI/Shop/PayDriver.pm @@ -5,9 +5,10 @@ use strict; use Class::InsideOut qw{ :std }; use Carp qw(croak); use Tie::IxHash; +use WebGUI::Exception::Shop; +use WebGUI::Inbox; use WebGUI::International; use WebGUI::HTMLForm; -use WebGUI::Exception::Shop; use WebGUI::Shop::Cart; use JSON; @@ -140,7 +141,6 @@ sub definition { WebGUI::Error::InvalidParam->throw(error => q{Must provide a session variable}) unless ref $session eq 'WebGUI::Session'; my $definition = shift || []; - my $i18n = WebGUI::International->new($session, 'PayDriver'); tie my %fields, 'Tie::IxHash'; @@ -163,11 +163,25 @@ sub definition { hoverHelp => $i18n->get('who can use help'), defaultValue => 1, }, - receiptMessage => { - fieldType => 'text', - label => $i18n->get('receipt message'), - hoverHelp => $i18n->get('receipt message help'), - defaultValue => undef, + receiptEmailTemplateId => { + fieldType => 'template', + namespace => "Shop/ReceiptEmail", + label => $i18n->get("receipt email template"), + hoverHelp => $i18n->get("receipt email template help"), + defaultValue => '', + }, + saleNotificationTemplateId => { + namespace => "Shop/SaleEmail", + fieldType => 'template', + label => $i18n->get("sale notification template"), + hoverHelp => $i18n->get("sale notification template help"), + defaultValue => '', + }, + saleNotificationGroupId => { + fieldType => 'group', + label => $i18n->get("sale notification group"), + hoverHelp => $i18n->get("sale notification group help"), + defaultValue => '3', }, ); @@ -367,6 +381,7 @@ sub getName { return $definition->[0]->{name}; } + #------------------------------------------------------------------- =head2 new ( $session, $paymentGatewayId ) @@ -414,6 +429,19 @@ the C method. #------------------------------------------------------------------- +=head2 processPayment () + +Should interact with the payment gateway and then return an array containing success/failure (as 1 or 0), transaction code (or payment gateway's transaction id), status code, and status message. Must be overridden by subclasses. + +=cut + +sub processPayment { + my $self = shift; + WebGUI::Error::OverrideMe->throw(error=>'Override processPayment()'); +} + +#------------------------------------------------------------------- + =head2 processPropertiesFromFormPost ( ) Updates ship driver with data from Form. @@ -438,6 +466,38 @@ sub processPropertiesFromFormPost { $self->update(\%properties); } +#------------------------------------------------------------------- + +=head2 processTransaction ( [ paymentAddress ] ) + +This method is responsible for handling success or failure from the payment processor, completing or denying the transaction, and sending out notification and receipt emails. Returns a WebGUI::Shop::Transaction object. + +=head3 paymentAddress + +A reference to a WebGUI::Shop::Address object that should be attached as payment information. Not required. + +=cut + +sub processTransaction { + my ($self, $paymentAddress) = @_; + my $cart = $self->getCart; + my $transaction = WebGUI::Shop::Transaction->create($self->session,{ + cart => $cart, + paymentMethod => $self, + paymentAddress => $paymentAddress, + }); + my ($success, $transactionCode, $statusCode, $statusMessage) = $self->processPayment; + if ($success) { + $transaction->completePurchase($cart, $transactionCode, $statusCode, $statusMessage); + $self->sendNotifications($transaction); + } + else { + $transaction->denyTransaction($transactionCode, $statusCode, $statusMessage); + } + return $transaction; +} + + #------------------------------------------------------------------- @@ -447,6 +507,39 @@ Accessor for the session object. Returns the session object. =cut + +#------------------------------------------------------------------- + +=head2 sendNotifications ( transaction ) + +Sends out a receipt and a sale notification to the buyer and the store owner respectively. + +=cut + +sub sendNotifications { + my ($self, $transaction) = @_; + my $session = $self->session; + my %var = (); # this needs to be filled in with transaction data for these emails + + + + + my $i18n = WebGUI::International->new($session,'PayDriver'); + my $inbox = WebGUI::Inbox->new($session); + $inbox->addMessage({ + userId => $transaction->get('userId'), + subject => $i18n->get('thank you for your order'), + message => WebGUI::Asset::Template->new($session, $self->get('emailReceiptTemplateId'))->process(\%var), + status => 'completed', + }); + $inbox->addMessage({ + groupId => $self->get('saleNotificationGroupId'), + subject => $i18n->get('a sale has been made'), + message => WebGUI::Asset::Template->new($session, $self->get('saleNotificationTemplateId'))->process(\%var), + status => 'completed', + }); +} + #------------------------------------------------------------------- =head2 update ( $options ) diff --git a/lib/WebGUI/Shop/PayDriver/Cash.pm b/lib/WebGUI/Shop/PayDriver/Cash.pm index 4e0472d87..09264064a 100644 --- a/lib/WebGUI/Shop/PayDriver/Cash.pm +++ b/lib/WebGUI/Shop/PayDriver/Cash.pm @@ -120,6 +120,12 @@ sub getCartTemplateVariables { #------------------------------------------------------------------- +sub processPayment { + return (1, undef, 1, 'Success'); +} + +#------------------------------------------------------------------- + sub www_displayStatus { } diff --git a/lib/WebGUI/Shop/Transaction.pm b/lib/WebGUI/Shop/Transaction.pm index 62b3ee045..361848c33 100644 --- a/lib/WebGUI/Shop/Transaction.pm +++ b/lib/WebGUI/Shop/Transaction.pm @@ -67,14 +67,18 @@ sub addItem { #------------------------------------------------------------------- -=head2 completePurchase ( cart, transactionCode, statusCode, statusMessage ) +=head2 completePurchase ( cart transactionCode, statusCode, statusMessage ) -See also denyPurchase(). Completes a purchase by updating the transaction as a success, and clearing the cart of it's items. +See also denyPurchase(). Completes a purchase by updating the transaction as a success, and clearing the cart of it's items. =head3 cart A reference to the current cart that's full of items just purchased. +=head3 paydriver + +A reference to the pay driver that just completed the transaction. + =head3 transactionCode The transaction id or code given by the payment gateway. @@ -92,7 +96,6 @@ The extended status message that came back from the payment gateway when trying sub completePurchase { my ($self, $cart, $transactionCode, $statusCode, $statusMessage) = @_; $cart->onCompletePurchase; - #$cart->completePurchase; $self->update({ transactionCode => $transactionCode, isSuccessful => 1, diff --git a/lib/WebGUI/i18n/English/PayDriver.pm b/lib/WebGUI/i18n/English/PayDriver.pm index 1742dac5a..0557e34c2 100644 --- a/lib/WebGUI/i18n/English/PayDriver.pm +++ b/lib/WebGUI/i18n/English/PayDriver.pm @@ -3,6 +3,54 @@ package WebGUI::i18n::English::PayDriver; use strict; our $I18N = { + 'thank you for your order' => { + message => q|Thank You For Your Order|, + lastUpdated => 0, + context => q|commerce setting| + }, + + 'a sale has been made' => { + message => q|A Sale Has Been Made|, + lastUpdated => 0, + context => q|commerce setting| + }, + + 'sale notification template' => { + message => q|Sale Notification Template|, + lastUpdated => 0, + context => q|commerce setting| + }, + + 'sale notification template help' => { + message => q|Which template should be used to generate the email that notifies this store owner about a new sale.|, + lastUpdated => 0, + context => q|commerce setting help| + }, + + 'sale notification group' => { + message => q|Sale Notification Group|, + lastUpdated => 0, + context => q|commerce setting| + }, + + 'sale notification group help' => { + message => q|Who should be notified of new transactions?|, + lastUpdated => 0, + context => q|commerce setting help| + }, + + 'receipt email template' => { + message => q|Receipt Email Template|, + lastUpdated => 0, + context => q|commerce setting| + }, + + 'receipt email template help' => { + message => q|Which template should be used to generate an email that will be sent to the user to acknowledge their purchase?|, + lastUpdated => 0, + context => q|commerce setting help| + }, + 'label' => { message => q|Label|, lastUpdated => 0, @@ -40,18 +88,6 @@ our $I18N = { context => q|Hover help for the group to use option.|, }, - 'receipt message' => { - message => q|Receipt message|, - lastUpdated => 0, - context => q|Label for the receipt message option.|, - }, - - 'receipt message help' => { - message => q|The message that will be attached to the receipt.|, - lastUpdated => 0, - context => q|Hover help the receipt message option.|, - }, - }; 1; diff --git a/lib/WebGUI/i18n/English/Shop.pm b/lib/WebGUI/i18n/English/Shop.pm index 656a52a88..c2430ff90 100644 --- a/lib/WebGUI/i18n/English/Shop.pm +++ b/lib/WebGUI/i18n/English/Shop.pm @@ -3,6 +3,30 @@ package WebGUI::i18n::English::Shop; use strict; our $I18N = { + 'my purchases template' => { + message => q|My Purchases Template|, + lastUpdated => 0, + context => q|commerce setting| + }, + + 'my purchases template help' => { + message => q|Which template should be used to display a user's order history?|, + lastUpdated => 0, + context => q|commerce setting help| + }, + + 'my purchases detail template' => { + message => q|My Purchases Detail Template|, + lastUpdated => 0, + context => q|commerce setting| + }, + + 'my purchases detail template help' => { + message => q|Which template should be used to display a user's order history detail? An individual sale rather than the whole transaction list.|, + lastUpdated => 0, + context => q|commerce setting help| + }, + 'username' => { message => q|User|, lastUpdated => 0,