Merge commit 'v7.10.17' into 8
Conflicts: docs/upgrades/upgrade_7.9.13-7.10.0.pl lib/WebGUI.pm lib/WebGUI/Asset/Template/TemplateToolkit.pm lib/WebGUI/Asset/Wobject/AssetReport.pm lib/WebGUI/Asset/Wobject/Thingy.pm lib/WebGUI/Form/Captcha.pm lib/WebGUI/Macro/AdminBar.pm lib/WebGUI/Shop/Cart.pm lib/WebGUI/Shop/PayDriver.pm lib/WebGUI/Shop/PayDriver/PayPal/ExpressCheckout.pm lib/WebGUI/Shop/PayDriver/PayPal/PayPalStd.pm lib/WebGUI/Shop/Transaction.pm lib/WebGUI/Workflow/Instance.pm lib/WebGUI/Workflow/Spectre.pm lib/WebGUI/i18n/English/PayDriver.pm t/Asset/Asset.t t/Asset/AssetExportHtml.t t/Asset/AssetLineage.t t/Asset/Wobject/Thingy.t
This commit is contained in:
commit
795d88e7e5
69 changed files with 972 additions and 170 deletions
|
|
@ -121,7 +121,7 @@ sub processPayment {
|
|||
my $self = shift;
|
||||
# Since we'll have to create a transaction before doing the actual tranasction, we let it fail
|
||||
# initially with a message that it is pending.
|
||||
# Unless the transaction result with _setPaymentStatus the transaction will fail.
|
||||
# Unless the transaction result is updated via _setPaymentStatus the transaction will fail.
|
||||
|
||||
my $success = $self->{_transactionSuccessful} || 0;
|
||||
my $id = $self->{_ogoneId} || undef;
|
||||
|
|
@ -129,7 +129,6 @@ sub processPayment {
|
|||
my $message = $self->{_statusMessage} || 'Waiting for checkout';
|
||||
|
||||
return ( $success, $id, $status, $message );
|
||||
return (0, undef, 1, 'Pending');
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ is a hashref, it will be modified in place.
|
|||
sub payPalForm {
|
||||
my $self = shift;
|
||||
my $args = ref $_[0] eq 'HASH' ? shift : {@_};
|
||||
$args->{VERSION} = '58.0';
|
||||
$args->{VERSION} = '2.3';
|
||||
$args->{USER} = $self->user;
|
||||
$args->{PWD} = $self->password;
|
||||
$args->{SIGNATURE} = $self->signature;
|
||||
|
|
@ -206,7 +206,6 @@ PayPal API spit back.
|
|||
|
||||
sub processPayment {
|
||||
my ( $self, $transaction ) = @_;
|
||||
my ( $isSuccess, $gatewayCode, $status, $message );
|
||||
|
||||
my $form = $self->payPalForm(
|
||||
METHOD => 'DoExpressCheckoutPayment',
|
||||
|
|
@ -317,6 +316,7 @@ sub www_sendToPayPal {
|
|||
if ($params) {
|
||||
unless ( $params->{ACK} =~ /^Success/ ) {
|
||||
my $log = sprintf "Paypal error: Request/response below: %s\n%s\n", Dumper($form), Dumper($params);
|
||||
$log .= $response->request->as_string;
|
||||
$session->log->error($log);
|
||||
$error = $i18n->get('internal paypal error');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ use URI;
|
|||
use URI::Escape;
|
||||
use LWP::UserAgent;
|
||||
use Readonly;
|
||||
use WebGUI::Shop::Transaction;
|
||||
|
||||
Readonly my $I18N => 'PayDriver_PayPalStd';
|
||||
|
||||
use Moose;
|
||||
|
|
@ -145,7 +147,9 @@ sub getButton {
|
|||
|
||||
# All the API stuff is done in paymentVariables; we'll just turn it into
|
||||
# hidden form fields here
|
||||
my $v = $self->paymentVariables;
|
||||
my $v = $self->paymentVariables;
|
||||
my $transaction = $self->processTransaction();
|
||||
$v->{custom} = $transaction->getId;
|
||||
my $fields = join "\n", map {
|
||||
WebGUI::Form::hidden( $session, { name => $_, value => $v->{$_} } )
|
||||
} (keys %$v);
|
||||
|
|
@ -177,6 +181,38 @@ sub getButton {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getPayPalParams
|
||||
|
||||
Using the tx form variable, dial up PayPal and ask them for details about the transaction.
|
||||
Return a hashreference of name/value pairs, along with PAYPAL_TX, the transactionId and
|
||||
PAYPAL_REQUEST_STATUS, the HTTP code from the response from PayPal.
|
||||
|
||||
=cut
|
||||
|
||||
sub getPayPalParams {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
# instead of relying on what was passed to us.
|
||||
return $self->{_params} if $self->{_params};
|
||||
my $tx = $session->form->process('tx');
|
||||
|
||||
my %form = (
|
||||
cmd => '_notify-synch',
|
||||
tx => $tx,
|
||||
at => $self->identityToken,
|
||||
);
|
||||
my $response = LWP::UserAgent->new->post($self->payPalUrl, \%form);
|
||||
my ($status, @lines) = split("\n", $response->content);
|
||||
my %params = map { split /=/ }
|
||||
map { uri_unescape($_) } @lines;
|
||||
$params{PAYPAL_REQUEST_STATUS} = $status;
|
||||
$params{PAYPAL_TX} = $tx;
|
||||
$self->{_params} = \%params;
|
||||
return $self->{_params};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 paymentVariables
|
||||
|
||||
Returns a hashref of the payment variables to be used as hidden form fields
|
||||
|
|
@ -225,9 +261,9 @@ sub paymentVariables {
|
|||
foreach my $item (@{ $cart->getItems}) {
|
||||
my $n = ++$counter;
|
||||
$params{"amount_$n"} = $item->getSku->getPrice;
|
||||
$params{"quantity_$n"} = $item->get('quantity');
|
||||
$params{"item_name_$n"} = $item->get('configuredTitle');
|
||||
$params{"item_number_$n"} = $item->get('itemId');
|
||||
$params{"quantity_$n"} = $item->quantity;
|
||||
$params{"item_name_$n"} = $item->configuredTitle;
|
||||
$params{"item_number_$n"} = $item->itemId;
|
||||
}
|
||||
|
||||
return \%params;
|
||||
|
|
@ -258,49 +294,49 @@ passed to us.
|
|||
=cut
|
||||
|
||||
sub processPayment {
|
||||
my ( $self, $transaction ) = @_;
|
||||
my $session = $self->session;
|
||||
my ( $self ) = @_;
|
||||
|
||||
# To prevent a spoofed post to this url, we'll get the info from paypal
|
||||
# instead of relying on what was passed to us.
|
||||
my $tx = $session->form->process('tx');
|
||||
my $success = $self->{_transactionSuccessful} || 0;
|
||||
my $id = $self->{_tx} || undef;
|
||||
my $status = $self->{_statusCode} || undef;
|
||||
my $message = $self->{_statusMessage} || 'Waiting for checkout';
|
||||
|
||||
my %form = (
|
||||
cmd => '_notify-synch',
|
||||
tx => $tx,
|
||||
at => $self->identityToken,
|
||||
);
|
||||
my $response = LWP::UserAgent->new->post($self->payPalUrl, \%form);
|
||||
my ($status, @lines) = split("\n", $response->content);
|
||||
my %params = map { split /=/ }
|
||||
map { uri_unescape($_) } @lines;
|
||||
return ( $success, $id, $status, $message );
|
||||
}
|
||||
|
||||
if ($status =~ /FAIL/) {
|
||||
my $message = '<table><tr><th>Field</th><th>Value</th></tr>';
|
||||
foreach my $key ( keys %params ) {
|
||||
$message .= "<tr><td>$key</td><td>$params{$key}</td></tr>";
|
||||
}
|
||||
$message .= '</table>';
|
||||
return ( 0, $tx, $status, $message );
|
||||
}
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
# Make sure the transaction is for this cart to prevent spoofing
|
||||
my $cartId = $self->getCart->getId;
|
||||
if ($params{custom} ne $cartId) {
|
||||
my $user = $session->user;
|
||||
my $name = $user->username;
|
||||
my $id = $user->userId;
|
||||
$session->log->warn("SECURITY WARNING: $name (id: $id) tried to " .
|
||||
"checkout cart $cartId with PayPal transaction $tx, which " .
|
||||
"did not match the cart we passed ($params{custom})");
|
||||
=head2 _setPaymentStatus ( transactionSuccessful, ogoneId, statusCode, statusMessage )
|
||||
|
||||
my $i18n = WebGUI::International->new( $session, $I18N );
|
||||
return ( 0, $tx, 'FAIL', $i18n->get('cart transaction mismatch') );
|
||||
}
|
||||
Update the internal status of a payment, so that the next call to processPayment
|
||||
returns the correct data.
|
||||
|
||||
$status = $params{payment_status};
|
||||
return ( 1, $tx, $status, $status, $status );
|
||||
} ## end sub processPayment
|
||||
=head3 transactionSuccessful
|
||||
|
||||
A boolean indicating whether or not the payment was successful.
|
||||
|
||||
=head3 tx
|
||||
|
||||
The PayPal issued transaction ID.
|
||||
|
||||
=head3 statusCode
|
||||
|
||||
The PayPal issued status code.
|
||||
|
||||
=head3 statusMessage
|
||||
|
||||
An updates status message
|
||||
|
||||
=cut
|
||||
|
||||
sub _setPaymentStatus {
|
||||
my ( $self ) = @_;
|
||||
|
||||
$self->{_transactionSuccessful} = shift || 0;
|
||||
$self->{_tx} = shift || undef;
|
||||
$self->{_statusCode} = shift || undef;
|
||||
$self->{_statusMessage} = shift || undef;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -311,11 +347,26 @@ Where paypal comes back to when a transaction has been completed.
|
|||
=cut
|
||||
|
||||
sub www_completeTransaction {
|
||||
my $self = shift;
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
|
||||
my $transaction = $self->processTransaction;
|
||||
my $params = $self->getPayPalParams;
|
||||
if ($params->{PAYPAL_REQUEST_STATUS} =~ /FAIL/) {
|
||||
my $message = "<table><tr><th>Field</th><th>Value</th></tr>\n";
|
||||
foreach my $key ( keys %{ $params } ) {
|
||||
$message .= sprintf "<tr><td>%s</td><td>%s</td></tr>\n", $key, $params->{key};
|
||||
}
|
||||
$message .= "</table>\n";
|
||||
return ( 0, $params->{PAYPAL_TX}, $params->{PAYPAL_REQUEST_STATUS}, $message );
|
||||
}
|
||||
my $transaction = eval { WebGUI::Shop::Transaction->new($session, $params->{custom}); };
|
||||
if (my $e = Exception::Class->caught) {
|
||||
return $self->displayPaymentError();
|
||||
}
|
||||
$self->_setPaymentStatus(1, $params->{PAYPAL_TX}, $params->{payment_status}, 'Complete');
|
||||
$self->processTransaction($transaction);
|
||||
|
||||
return $transaction->get('isSuccessful')
|
||||
return $transaction->isSuccessful
|
||||
? $transaction->thankYou
|
||||
: $self->displayPaymentError($transaction);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue