Initial support for Google Checkout as a merchant processor.

        Patch by mark. 

diffs (621 lines):

diff -r 4660678283bb -r f30c9dfe7830 bin/upgrading/en.dat
--- a/bin/upgrading/en.dat      Tue Feb 02 06:56:18 2010 +0000
+++ b/bin/upgrading/en.dat      Wed Feb 03 01:21:16 2010 +0000
@@ -4595,6 +4595,8 @@ widget.shopcart.paymentmethod.checkmoney
 
 widget.shopcart.paymentmethod.creditcardpp=Credit Card
 
+widget.shopcart.paymentmethod.gco=Google Checkout Account
+
 widget.shopcart.paymentmethod.paypal=PayPal Account
 
 widget.shopcart.total=Total:
diff -r 4660678283bb -r f30c9dfe7830 bin/upgrading/update-db-general.pl
--- a/bin/upgrading/update-db-general.pl        Tue Feb 02 06:56:18 2010 +0000
+++ b/bin/upgrading/update-db-general.pl        Wed Feb 03 01:21:16 2010 +0000
@@ -2867,6 +2867,30 @@ CREATE table externalaccount (
 )
 EOC
 
+register_tablecreate('gco_log', <<'EOC');
+CREATE TABLE gco_log (
+    gcoid bigint unsigned not null,
+    ip varchar(15) not null,
+    transtime int unsigned not null,
+    req_content text not null,
+
+    index (gcoid)
+)
+EOC
+
+register_tablecreate('gco_map', <<'EOC');
+CREATE TABLE gco_map (
+    gcoid bigint unsigned not null,
+    cartid int unsigned not null,
+
+    email varchar(255),
+    contactname varchar(255),
+
+    index (gcoid),
+    unique (cartid)
+)
+EOC
+
 register_tablecreate('pp_tokens', <<'EOC');
 CREATE TABLE pp_tokens (
     ppid int unsigned not null auto_increment,
diff -r 4660678283bb -r f30c9dfe7830 cgi-bin/DW/Shop.pm
--- a/cgi-bin/DW/Shop.pm        Tue Feb 02 06:56:18 2010 +0000
+++ b/cgi-bin/DW/Shop.pm        Wed Feb 03 01:21:16 2010 +0000
@@ -85,6 +85,10 @@ our %PAYMENTMETHODS = (
         id => 3,
         class => 'CreditCardPP',
     },
+    gco => {
+        id => 4,
+        class => 'GoogleCheckout',
+    },
 );
 
 
diff -r 4660678283bb -r f30c9dfe7830 cgi-bin/DW/Shop/Engine.pm
--- a/cgi-bin/DW/Shop/Engine.pm Tue Feb 02 06:56:18 2010 +0000
+++ b/cgi-bin/DW/Shop/Engine.pm Wed Feb 03 01:21:16 2010 +0000
@@ -20,12 +20,14 @@ use DW::Shop::Engine::CheckMoneyOrder;
 use DW::Shop::Engine::CheckMoneyOrder;
 use DW::Shop::Engine::CreditCardPP;
 use DW::Shop::Engine::PayPal;
+use DW::Shop::Engine::GoogleCheckout;
 
 # get( $method, $cart )
 #
 # returns the proper subclass for the given payment method, if one exists
 sub get {
     return DW::Shop::Engine::PayPal->new( $_[2] ) if $_[1] eq 'paypal';
+    return DW::Shop::Engine::GoogleCheckout->new( $_[2] ) if $_[1] eq 'gco';
     return DW::Shop::Engine::CreditCardPP->new( $_[2] ) if $_[1] eq 
'creditcardpp';
     return DW::Shop::Engine::CheckMoneyOrder->new( $_[2] ) if $_[1] eq 
'checkmoneyorder';
 
diff -r 4660678283bb -r f30c9dfe7830 cgi-bin/DW/Shop/Engine/CheckMoneyOrder.pm
--- a/cgi-bin/DW/Shop/Engine/CheckMoneyOrder.pm Tue Feb 02 06:56:18 2010 +0000
+++ b/cgi-bin/DW/Shop/Engine/CheckMoneyOrder.pm Wed Feb 03 01:21:16 2010 +0000
@@ -26,7 +26,7 @@ use base qw/ DW::Shop::Engine /;
 
 # new( $cart )
 #
-# instantiates a new PayPal engine for the given cart
+# instantiates a new CMO engine for the given cart
 sub new {
     return bless { cart => $_[1] }, $_[0];
 }
@@ -111,7 +111,7 @@ sub cancel_order {
     my $self = $_[0];
 
     # ensure the cart is in open state
-    return $self->error( 'paypal.engbadstate' )
+    return $self->error( 'cmo.engbadstate' )
         unless $self->cart->state == $DW::Shop::STATE_OPEN;
 
     return 1;
diff -r 4660678283bb -r f30c9dfe7830 cgi-bin/DW/Shop/Engine/GoogleCheckout.pm
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/cgi-bin/DW/Shop/Engine/GoogleCheckout.pm  Wed Feb 03 01:21:16 2010 +0000
@@ -0,0 +1,259 @@
+#!/usr/bin/perl
+#
+# DW::Shop::Engine::GoogleCheckout
+#
+# The interface to Google Checkout's flow.  Responsible for doing all of the
+# work to talk to this merchant processor.
+#
+# Authors:
+#      Mark Smith <[email protected]>
+#
+# Copyright (c) 2010 by Dreamwidth Studios, LLC.
+#
+# This program is free software; you may redistribute it and/or modify it under
+# the same terms as Perl itself.  For a copy of the license, please reference
+# 'perldoc perlartistic' or 'perldoc perlgpl'.
+#
+
+package DW::Shop::Engine::GoogleCheckout;
+
+use strict;
+use Carp qw/ croak confess /;
+use Storable qw/ nfreeze thaw /;
+use Google::Checkout::General::GCO;
+use Google::Checkout::General::MerchantCheckoutFlow;
+use Google::Checkout::General::DigitalContent;
+use Google::Checkout::General::ShoppingCart;
+use Google::Checkout::Command::ChargeOrder;
+use Google::Checkout::General::Util qw/ is_gco_error /;
+
+use base qw/ DW::Shop::Engine /;
+
+
+# new( $cart )
+#
+# instantiates a new GCO engine for the given cart
+sub new {
+    return bless { cart => $_[1] }, $_[0];
+}
+
+
+# new_from_cart( $cart )
+#
+# constructs an engine from a given cart.
+sub new_from_cart {
+    my ( $class, $cart ) = @_;
+
+    my $dbh = DW::Pay::get_db_writer()
+        or die "Database temporarily unavailable.\n"; # no object yet
+
+    my ( $gcoid, $cn, $em ) =
+        $dbh->selectrow_array( 'SELECT gcoid, contactname, email FROM gco_map 
WHERE cartid = ?', undef, $cart->id );
+
+    # if they have no row in the database, then this is a new cart that hasn't
+    # yet really been through the flow
+    return bless { cart => $cart }, $class
+        unless $gcoid;
+
+    # it HAS, we have a row, so populate with all of the data we have
+    return bless {
+        gcoid => $gcoid,
+        contactname => $cn,
+        email => $em,
+        cart => $cart,
+    }, $class;
+}
+
+
+# new_from_gcoid( $gcoid )
+#
+# constructs an engine from a given google order number.
+sub new_from_gcoid {
+    my ( $class, $gcoid ) = @_;
+
+    my $dbh = DW::Pay::get_db_writer()
+        or die "Database temporarily unavailable.\n"; # no object yet
+
+    my ( $cartid, $cn, $em ) =
+        $dbh->selectrow_array( 'SELECT cartid, contactname, email FROM gco_map 
WHERE gcoid = ?', undef, $gcoid );
+
+    my $cart = DW::Shop::Cart->get_from_cartid( $cartid )
+        or die "Unable to load cart from Google Order Number $gcoid.\n";
+
+    # it HAS, we have a row, so populate with all of the data we have
+    return bless {
+        gcoid => $gcoid,
+        contactname => $cn,
+        email => $em,
+        cart => $cart,
+    }, $class;
+}
+
+
+# checkout_url()
+#
+# given a shopping cart full of Stuff, build a URL for us to send the user to
+# to initiate the checkout process.
+sub checkout_url {
+    my $self = $_[0];
+
+    # make sure that the cart contains something that costs something.  since
+    # this check should have been done above, we die hardcore here.
+    my $cart = $self->cart;
+    die "Constraints not met: cart && cart->has_items && cart->has_total > 
0.00.\n"
+        unless $cart && $cart->has_items && $cart->total > 0.00;
+
+    # and, just in case something terrible happens, make sure our state is good
+    die "Cart not in valid state!\n"
+        unless $cart->state == $DW::Shop::STATE_OPEN;
+
+    # flow for this particular order
+    my $flow = Google::Checkout::General::MerchantCheckoutFlow->new(
+        edit_cart_url         => "$LJ::SITEROOT/shop/cart",
+        continue_shopping_url => "$LJ::SITEROOT/shop",
+        buyer_phone           => 'false',
+    );
+
+    # and now build us a cart
+    my $gcart = Google::Checkout::General::ShoppingCart->new(
+        expiration    => "+1 month",
+        private       => $cart->id,
+        checkout_flow => $flow,
+    );
+
+    # now we have to stick in data for each of the items in the cart
+    foreach my $item ( @{ $cart->items } ) {
+        my $gitem = Google::Checkout::General::DigitalContent->new(
+            name        => $item->class_name,
+            description => $item->short_desc,
+            price       => $item->cost,
+            quantity    => 1,
+            private     => $item->id,
+            delivery_method => 
Google::Checkout::General::DigitalContent::EMAIL_DELIVERY,
+        );
+
+        $gcart->add_item( $gitem );
+    }
+
+    # now get a URL from Google, or try
+    my $res = $self->gco->checkout( $gcart );
+    return $self->error( "Google Checkout Error: $res" )
+        if is_gco_error $res;
+
+    # and finally, this is the URL!
+    return $res;
+}
+
+
+# cancel_order()
+#
+# cancels the order and doesn't send any money
+sub cancel_order {
+    # does not apply to this payment system ...
+    die "Does not apply to Google Checkout.\n";
+}
+
+
+# this sends the command to Google Checkout to actually charge the order.  it 
must
+# be open and have a GON/GCOID which means it went through the new order flow.
+sub charge_order {
+    my $self = $_[0];
+    return
+        unless $self->gcoid > 0 &&
+               $self->cart->state == $DW::Shop::STATE_OPEN;
+
+    my $charge_order = Google::Checkout::Command::ChargeOrder->new(
+        order_number => $self->gcoid,
+        amount       => $self->cart->display_total,
+    );
+
+    my $response = $self->gco->command( $charge_order );
+    die "Failed to charge order: $response\n"
+        if is_gco_error $response;
+
+    # we are now pending payment for this cart ...
+    $self->cart->state( $DW::Shop::STATE_PEND_PAID );
+}
+
+
+# called by the system when we get a posted notification of some sort
+sub process_notification {
+    my ( $class, $form ) = @_;
+
+    # if no order number, invalid!
+    my $gon = $form->{'google-order-number'}
+        or return;
+
+    # log the request
+    my $dbh = DW::Pay::get_db_writer()
+        or die "failed, please retry later\n";
+    $dbh->do(
+        q{INSERT INTO gco_log (gcoid, ip, transtime, req_content)
+          VALUES (?, ?, UNIX_TIMESTAMP(), ?)},
+        undef, $gon, BML::get_remote_ip(), nfreeze( $form )
+    );
+    die "failed to insert: " . $dbh->errstr . "\n"
+        if $dbh->err;
+
+    # now that it's logged, we can do some processing depending on what type 
it is
+    if ( $form->{_type} eq 'new-order-notification' ) {
+        my $cart = DW::Shop::Cart->get_from_cartid( $1 )
+            if $form->{'shopping-cart.merchant-private-data'} =~ 
m!note>(\d+)</merch!;
+
+        # now ensure the cart is good ...
+        return 1
+            unless $cart &&
+                   $cart->state == $DW::Shop::STATE_OPEN &&
+                   $cart->paymentmethod eq 'gco' &&
+                   $cart->display_total == $form->{'order-total'};
+
+        $dbh->do(
+            q{INSERT INTO gco_map (gcoid, cartid, email, contactname)
+              VALUES (?, ?, ?, ?)},
+            undef, $gon, $cart->id, $form->{'buyer-billing-address.email'}, 
$form->{'buyer-billing-address.contact-name'}
+        );
+        die "failed to update gco_map: " . $dbh->errstr . "\n"
+            if $dbh->err;
+
+        # we need to actually charge the order now ...
+        my $eng = $class->new_from_gcoid( $gon )
+            or die "failed to load engine for Google Order Number $gon\n";
+        $eng->charge_order;
+
+    # if we actually captured some money, then we need to make sure that the 
order
+    # gets to be marked as ready to go
+    } elsif ( $form->{_type} eq 'charge-amount-notification' ) {
+        my $eng = $class->new_from_gcoid( $gon )
+            or die "failed to load engine for Google Order Number $gon\n";
+
+        # sanity check again, make sure our cart still looks good
+        return 1
+            unless $eng->cart->state == $DW::Shop::STATE_PEND_PAID &&
+                   $eng->cart->paymentmethod eq 'gco' &&
+                   $eng->cart->display_total == $form->{'total-charge-amount'};
+
+        # looks good, mark it paid so it gets processed
+        $eng->cart->state( $DW::Shop::STATE_PAID );
+
+        # NOTE: do not send an email here.  Google requests that people who 
implement
+        # Google Checkout do not actually send a confirmation email, as they 
will
+        # take care of that when the user places the order, and one email 
should be
+        # enough for most purposes.
+    }
+}
+
+
+# accessors
+sub gcoid { $_[0]->{gcoid} }
+sub cart { $_[0]->{cart} }
+sub contactname { $_[0]->{contactname} }
+sub email { $_[0]->{email} }
+
+
+# returns a Google Checkout object with our proper server configuration
+sub gco {
+    return Google::Checkout::General::GCO->new( config_path => 
"$LJ::HOME/etc/google-checkout.conf" );
+}
+
+
+1;
diff -r 4660678283bb -r f30c9dfe7830 cgi-bin/LJ/Widget/ShopCart.pm
--- a/cgi-bin/LJ/Widget/ShopCart.pm     Tue Feb 02 06:56:18 2010 +0000
+++ b/cgi-bin/LJ/Widget/ShopCart.pm     Wed Feb 03 01:21:16 2010 +0000
@@ -97,34 +97,32 @@ sub render_body {
         }
         $ret .= "</tr>";
     }
-    $ret .= "<tr><td colspan='" . $colspan . "' class='total'>" . $class->ml( 
'widget.shopcart.total' ) . " \$" . $cart->display_total . " USD</td></tr>";
+
+    my $buttons = '&nbsp;';
+    unless ( $opts{receipt} ) {
+        $buttons = $class->html_submit( removeselected => $class->ml( 
'widget.shopcart.btn.removeselected' ) ) . " " .
+                   $class->html_submit( discard => $class->ml( 
'widget.shopcart.btn.discard' ) ) . "</p>";
+    }
+
+    $ret .= "<tr><td class='total' style='border-right: none; text-align: 
left;' colspan='3'>$buttons</td>";
+    $ret .= "<td style='border-left: none;' colspan='" . ($colspan-3) .
+            "' class='total'>" . $class->ml( 'widget.shopcart.total' ) . " \$" 
. $cart->display_total . " USD</td></tr>";
     $ret .= "</table>";
 
     unless ( $opts{receipt} ) {
-        $ret .= "<div class='shop-cart-btn'>";
+        $ret .= "<div class='shop-cart-btn'><p>";
 
-        $ret .= "<p>" . $class->html_submit( removeselected => $class->ml( 
'widget.shopcart.btn.removeselected' ) ) . " ";
-        $ret .= $class->html_submit( discard => $class->ml( 
'widget.shopcart.btn.discard' ) ) . "</p>";
+        # google has very specific rules about where the buttons go and how to 
display them
+        # ... so we have to abide by that
+        if ( LJ::is_enabled( 'googlecheckout' ) ) {
+            $ret .= '<input type="image" name="' . $class->input_prefix . 
'_checkout_gco" src="https://checkout.google.com/buttons/checkout.gif?' .
+                    
'merchant_id=&w=180&h=46&style=trans&variant=text&loc=en_US" alt="Use Google 
Checkout" style="vertical-align: middle;" /> or use ';
+        }
 
-        my @paypal_option;
-        @paypal_option = (
-            paypal => $class->ml( 'widget.shopcart.paymentmethod.paypal' ),
-            creditcardpp => $class->ml( 
'widget.shopcart.paymentmethod.creditcardpp' ),
-        )
-            if keys %LJ::PAYPAL_CONFIG;
-        $ret .= "<p>" . $class->ml( 'widget.shopcart.paymentmethod' ) . " ";
-        $ret .= $class->html_select(
-            name => 'paymentmethod',
-            selected => keys %LJ::PAYPAL_CONFIG ? 'paypal' : 'checkmoneyorder',
-            list => [
-                @paypal_option,
-                checkmoneyorder => $class->ml( 
'widget.shopcart.paymentmethod.checkmoneyorder' ),
-            ],
-        ) . " ";
-        $ret .= $class->html_submit( checkout => $class->ml( 
'widget.shopcart.btn.checkout' ) ) . "</p>";
+        # check or money order button
+        $ret .= $class->html_submit( checkout_cmo => $class->ml( 
'widget.shopcart.paymentmethod.checkmoneyorder' ) );
 
-        $ret .= "</div>";
-
+        $ret .= "</p></div>";
         $ret .= $class->end_form
     }
 
@@ -134,9 +132,14 @@ sub handle_post {
 sub handle_post {
     my ( $class, $post, %opts ) = @_;
 
-    # check out
-    return BML::redirect( 
"$LJ::SITEROOT/shop/checkout?method=$post->{paymentmethod}" )
-        if $post->{checkout};
+    # checkout methods depend on which button was clicked
+    my $cm;
+    $cm = 'gco' if LJ::is_enabled( 'googlecheckout' ) && ( 
$post->{checkout_gco} || $post->{'checkout_gco.x'} );
+    $cm = 'checkmoneyorder' if $post->{checkout_cmo};
+
+    # check out?
+    return BML::redirect( "$LJ::SITEROOT/shop/checkout?method=$cm" )
+        if defined $cm;
 
     # remove selected items
     if ( $post->{removeselected} ) {
diff -r 4660678283bb -r f30c9dfe7830 doc/config-local.pl.txt
--- a/doc/config-local.pl.txt   Tue Feb 02 06:56:18 2010 +0000
+++ b/doc/config-local.pl.txt   Wed Feb 03 01:21:16 2010 +0000
@@ -51,21 +51,22 @@
             private_key => $DW::PRIVATE::RECAPTCHA{private_key},
         );
 
-    # PayPal configuration
-    %PAYPAL_CONFIG = (
-            # express checkout URL, the token gets appended to this
-            url       => 
'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=',
-            api_url   => 'https://api-3t.sandbox.paypal.com/nvp',
+    # PayPal configuration.  If you want to use PayPal, uncomment this
+    # section and make sure to fill in the fields at the bottom of 
config-private.pl.
+    #%PAYPAL_CONFIG = (
+    #        # express checkout URL, the token gets appended to this
+    #        url       => 
'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=',
+    #        api_url   => 'https://api-3t.sandbox.paypal.com/nvp',
 
-            # credentials for the API
-            user      => $DW::PRIVATE::PAYPAL{user},
-            password  => $DW::PRIVATE::PAYPAL{password},
-            signature => $DW::PRIVATE::PAYPAL{signature},
+    #        # credentials for the API
+    #        user      => $DW::PRIVATE::PAYPAL{user},
+    #        password  => $DW::PRIVATE::PAYPAL{password},
+    #        signature => $DW::PRIVATE::PAYPAL{signature},
 
-            # set this to someone who is responsible for getting emails about
-            # various PayPal related events
-            email     => $DW::PRIVATE::PAYPAL{email},
-        );
+    #        # set this to someone who is responsible for getting emails about
+    #        # various PayPal related events
+    #        email     => $DW::PRIVATE::PAYPAL{email},
+    #    );
 
     # if you define these, little help bubbles appear next to common
     # widgets to the URL you define:
diff -r 4660678283bb -r f30c9dfe7830 doc/google-checkout.conf.txt
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/google-checkout.conf.txt      Wed Feb 03 01:21:16 2010 +0000
@@ -0,0 +1,10 @@
+# Change these.
+MERCHANT_ID = 1234
+MERCHANT_KEY = abcd
+BASE_GCO_SERVER = https://sandbox.google.com/checkout/cws/v2/Merchant
+
+# Do not change.
+XML_SCHEMA = http://checkout.google.com/schema/2
+CURRENCY_SUPPORTED = USD
+XML_VERSION = 1.0
+XML_ENCODING = UTF-8
diff -r 4660678283bb -r f30c9dfe7830 etc/config.pl
--- a/etc/config.pl     Tue Feb 02 06:56:18 2010 +0000
+++ b/etc/config.pl     Wed Feb 03 01:21:16 2010 +0000
@@ -183,6 +183,7 @@
                  eventlogrecord => 1,
                  feedster_search => 0,
                  free_create => 1,
+                 googlecheckout => 1,
                  'interests-findsim' => 0,
                  memories => 0,
                  opt_findbyemail => 1,
diff -r 4660678283bb -r f30c9dfe7830 htdocs/admin/pay/view.bml
--- a/htdocs/admin/pay/view.bml Tue Feb 02 06:56:18 2010 +0000
+++ b/htdocs/admin/pay/view.bml Wed Feb 03 01:21:16 2010 +0000
@@ -6,6 +6,7 @@
 {
     use strict;
     use vars qw(%GET %POST);
+    use Storable qw/ thaw /;
 
     my $remote = LJ::get_remote();
     my @displayprivs = ( "payments" );
@@ -130,15 +131,28 @@ EOF
         # make an educated guess at durl-ing something
         my $durl = sub {
             my $val = shift;
+
+            my $hr;
+            my $out = sub {
+                foreach ( qw/ SIGNATURE USER PWD / ) {
+                    $hr->{$_} = '<em>redacted</em>'
+                        if exists $hr->{$_};
+                }
+                return join( '<br />', map { "<strong>$_:</strong> $hr->{$_}" 
} sort keys %$hr );
+            };
+
+            # first see if it's Storable encoded ...
+            eval {
+                my $x = thaw( $val );
+                $hr = $x if $x && ref $x eq 'HASH';
+            };
+            return $out->() if $hr;
+
+            # and now fall back to urlencoded ...
             return $val
                 unless $val =~ /&/ && $val =~ /=/;
-            my ( $hr, $ar ) = ( {}, [] );
-            LJ::decode_url_string( $val, $hr, $ar );
-            foreach ( qw/ SIGNATURE USER PWD / ) {
-                $hr->{$_} = '<em>redacted</em>'
-                    if exists $hr->{$_};
-            }
-            return "<br />-----------<br />" . join( '<br />', map { 
"<strong>$_:</strong> $hr->{$_}" } sort keys %$hr );
+            LJ::decode_url_string( $val, $hr );
+            return $out->();
         };
 
         my $dbh = LJ::get_db_writer();
@@ -155,7 +169,7 @@ EOF
             unless $rows && @$rows;
 
         my @cols = sort { $a cmp $b } keys %{ $rows->[0] };
-        $body .= q{<table><tr><th>};
+        $body .= q{<table border=1 cellpadding=5><tr><th>};
         $body .= join( '</th><th>', @cols );
         $body .= q{</th></tr>};
 
@@ -189,6 +203,18 @@ EOF
         # now show the pp_log log
         $body .= "<h2>raw: pp_log (PayPal raw log)</h2>";
         $dump->( 'SELECT * FROM pp_log WHERE ppid = ?', $engine->ppid );
+
+    } elsif ( $classname eq 'GoogleCheckout' ) {
+        # show the payer's details.
+        $body .= "<h2>GCO Payer Details</h2>";
+        $body .= "<table border='1'>";
+        $body .= "<tr><th>Contact Name:</th><td>" . $engine->contactname . 
"</td></tr>";
+        $body .= "<tr><th>GCO Email Address:</th><td>" . $engine->email . 
"</td></tr>";
+        $body .= "</table>";
+
+        # now show the pp_trans log
+        $body .= "<h2>raw: gco_log (GCO raw)</h2>";
+        $dump->( 'SELECT * FROM gco_log WHERE gcoid = ?', $engine->gcoid );
 
     } elsif ( $classname eq 'CheckMoneyOrder' ) {
         # show the payer's details.
diff -r 4660678283bb -r f30c9dfe7830 htdocs/shop/gco_notify.bml
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/shop/gco_notify.bml        Wed Feb 03 01:21:16 2010 +0000
@@ -0,0 +1,28 @@
+<?_code
+{
+    #
+    # shop/gco_notify.bml
+    #
+    # Notification system for Google Checkout.
+    #
+    # Authors:
+    #      Mark Smith <[email protected]>
+    #
+    # Copyright (c) 2010 by Dreamwidth Studios, LLC.
+    #
+    # This program is free software; you may redistribute it and/or modify it 
under
+    # the same terms as Perl itself.  For a copy of the license, please 
reference
+    # 'perldoc perlartistic' or 'perldoc perlgpl'.
+    #
+
+    use strict;
+    use vars qw( %FORM );
+
+    return BML::redirect( "$LJ::SITEROOT/" )
+        unless LJ::is_enabled( 'payments' );
+
+    DW::Shop::Engine::GoogleCheckout->process_notification( \%FORM );
+
+    return "failure";
+}
+_code?>
diff -r 4660678283bb -r f30c9dfe7830 htdocs/shop/receipt.bml.text
--- a/htdocs/shop/receipt.bml.text      Tue Feb 02 06:56:18 2010 +0000
+++ b/htdocs/shop/receipt.bml.text      Wed Feb 03 01:21:16 2010 +0000
@@ -31,6 +31,8 @@
 
 .cart.paymentmethod.creditcardpp=Credit Card
 
+.cart.paymentmethod.gco=Google Checkout Account
+
 .cart.paymentmethod.paypal=PayPal Account
 
 .error.invalidordernum=Your order number is invalid.
_______________________________________________
dw-changelog mailing list
[email protected]
http://lists.dwscoalition.org/mailman/listinfo/dw-changelog

Reply via email to