Permalink
Browse files

Rework the transaction processor

  • Loading branch information...
1 parent 1a7ca95 commit 30b3d5c5ddcdbf9e77f1c247803f5258ba0da35a Luke Closs committed Jun 14, 2012
Showing with 84 additions and 52 deletions.
  1. +0 −1 bin/job-runner
  2. +75 −44 bin/process-transactions
  3. +2 −1 bin/send-receipt
  4. +2 −0 lib/Biopay/Daemon.pm
  5. +5 −6 lib/Biopay/PaymentProcessor.pm
View
@@ -11,7 +11,6 @@ use Biopay::EmailReceipt qw/parse_email/;
use Biopay::Transaction;
use Biopay::Util qw/email_admin email_board host/;
use Try::Tiny;
-use List::Util qw/sum/;
my $daemon = Biopay::Daemon->new(
name => 'job-runner',
View
@@ -9,21 +9,41 @@ use Biopay::Member;
use Biopay::Prices;
use Biopay::PaymentProcessor;
use Biopay::Receipt;
+use Biopay::Transaction;
use Getopt::Long;
+use Biopay::Util qw/email_admin email_board host/;
+use List::Util qw/sum/;
+use Try::Tiny;
BEGIN {
Dancer::Config::setting('appdir',realpath("$FindBin::Bin/.."));
Dancer::Config::setting('views',realpath("$FindBin::Bin/../views"));
Dancer::Config::load();
}
+my $force;
+my $verbose = 1;
+my $dont_send_email;
+GetOptions(
+ 'f|force' => \$force,
+ 'v|verbose' => \$verbose,
+ 'd|dont-send' => \$dont_send_email,
+);
+
my $member_id = shift || die "USAGE: $0 <member_id>";;
my $member = Biopay::Member->By_id($member_id);
+
+if ($member->billing_error and !$force) {
+ print "Member $member_id has a billing error. Use --force if you are sure.\n";
+ exit 0;
+}
+
my $txns = $member->unpaid_transactions;
unless (@$txns) {
- print "Member $member_id has no un-paid transactions.\n";
- exit;
+ print "Member $member_id has no un-paid transactions. Exiting.\n";
+ exit 0;
}
+print "Member $member_id has @{[scalar(@$txns)]} unpaid transactions.\n" if $verbose;
my $total = sum map { $_->price } @$txns;
print ' (Bio-' . $member->id . ":\$$total) ";
@@ -47,40 +67,29 @@ if ($need_to_renew_membership) {
};
}
-my $error = "Order '$order_num' not yet processed.";
-try {
- try {
- Biopay::PaymentProcessor->new->process(
- order_num => $order_num,
- amount => $total,
- hash => $member->payment_hash,
- );
- Biopay::Receipt->Create(
- member_id => $member->id,
- order_num => $order_num,
- amount => $total,
- items => $items,
- );
+use Data::Dumper;
+print Dumper $items if $verbose;
- $error = "Processed payment, but didn't update member yet.";
- # Update the member, if necessary
- if ($need_to_renew_membership) {
- $member->renew_membership;
- print ' (Renewed membership for: ' . $member->id . ') ';
- }
- unfreeze_member($member) if $member->frozen;
- }
- catch {
- my $err = $_;
+my $error = "Order '$order_num' not yet processed.";
+eval {
+ my ($ok, $msg) = Biopay::PaymentProcessor->new->process(
+ order_num => $order_num,
+ amount => $total,
+ hash => $member->payment_hash,
+ );
+ print "Processed payment: ($ok, @{[$msg||'']})\n" if $verbose;
+ if (!$ok) {
+ my $err = $msg;
+ print "Error processing payment for @{[$member->id]} - $err";
# There was an error processing payment for this member. Set their
# billing_error flag, so that we don't retry until it is cleared
- $member->billing_error($err);
- $member->billing_error_epoch(time());
- $member->frozen(1);
- create_freeze_job($member, 'freeze');
try {
+ $member->billing_error($err);
+ $member->billing_error_epoch(time());
+ $member->frozen(1);
$member->save;
print ' (Freeze:' . $member->id . ') ';
+ $member->send_billing_error_email($err, $total) unless $dont_send_email;
}
catch {
my $save_err = $_;
@@ -90,11 +99,27 @@ try {
. "\nSave error was: $save_err"
. "\nPayment error was: $err");
};
- $member->send_billing_error_email($err, $total);
- # Re-raise error so that it is reported properly.
- die $err;
- };
+ create_freeze_job($member, 'freeze');
+
+ print "Transaction failed. Exiting.\n" if $verbose;
+ exit 0;
+ }
+
+ Biopay::Receipt->Create(
+ member_id => $member->id,
+ order_num => $order_num,
+ amount => $total,
+ items => $items,
+ );
+
+ $error = "Processed payment, but didn't update member yet.";
+ # Update the member, if necessary
+ if ($need_to_renew_membership) {
+ $member->renew_membership;
+ print ' (Renewed membership for: ' . $member->id . ') ';
+ }
+ unfreeze_member($member) if $member->frozen;
$error = "Order '$order_num' processed but txns not marked as paid.";
for my $txn (@$txns) {
@@ -114,15 +139,20 @@ try {
$error = "Order '$order_num' processed, txns marked as paid, but "
. "receipt is not sent.";
- Biopay::Command->Create(
- command => 'send-receipt',
- member_id => $member->id,
- txn_ids => [ map { $_->id } @$txns ],
- ($need_to_renew_membership ? (dues => $membership_price) : ())
- );
-}
-catch {
- my $err = $_;
+ if ($dont_send_email) {
+ print "Skipping receipt!\n";
+ }
+ else {
+ Biopay::Command->Create(
+ command => 'send-receipt',
+ member_id => $member->id,
+ txn_ids => [ map { $_->id } @$txns ],
+ ($need_to_renew_membership ? (dues => $membership_price) : ())
+ );
+ }
+};
+if ($@) {
+ $err = $@;
error $err;
email_admin("Error processing payment $order_num",
@@ -133,7 +163,8 @@ catch {
);
}
-exit;
+print "Transaction complete. Exiting.\n";
+exit 0;
sub create_freeze_job {
my $member = shift;
View
@@ -18,11 +18,12 @@ BEGIN {
my %opts;
GetOptions( \%opts,
'resend-last|r=i',
+ 'for=i',
) or usage();
my $job_id = shift;
my $member;
-if (my $mid = $opts{'resend-last'}) {
+if (my $mid = $opts{'resend-last'} || $opts{for}) {
$member = Biopay::Member->By_id($mid);
my $receipt = $member->last_receipt;
die "Couldn't find any receipts for member #$mid" unless $receipt;
View
@@ -84,11 +84,13 @@ method run {
}
catch {
(my $first_line = $_) =~ s/\n.+//s;
+ unless ($first_line =~ m/malformed JSON string/) {
warn $self->name . " Error: $_";
email_admin(
"Un-caught cardlock error: $first_line",
"Not sure what happened: $_",
);
+ }
};
finally {
print $self->name, " shutting down.\n";
@@ -15,7 +15,7 @@ method process {
my $msg = "Payment: $p{order_num} for \$$p{amount}";
$msg .= " TEST" if config->{merchant_test};
print " ($msg) ";
- return if config->{merchant_test};
+ return (1, undef) if config->{merchant_test};
my $resp = $self->ua->post(
'https://www.beanstream.com/scripts/process_transaction.asp',
@@ -30,18 +30,17 @@ method process {
my $qs = URI::Query->new($resp->content);
my %result = $qs->hash;
(my $msg = $result{messageText}||'') =~ s/\+/ /g;
- return "Transaction $p{order_num} is approved." if $result{trnApproved};
+ return (1, "Transaction $p{order_num} is approved.") if $result{trnApproved};
if ($msg =~ m/Duplicate Transaction/) {
# This dup is an error, but we'll return success. This only
# should happen in testing.
- return "Transaction $p{order_num} was a dup.";
+ return (1, "Transaction $p{order_num} was a dup.");
}
- die "Payment of \$$p{amount} failed. Reason: $msg\n";
+ return (0, "Payment of \$$p{amount} failed. Reason: $msg");
}
else {
- die "Payment of \$$p{amount} failed. Reason: "
- . $resp->status_line . "\n";
+ return (0, "Payment of \$$p{amount} failed. Reason: " . $resp->status_line);
}
}

0 comments on commit 30b3d5c

Please sign in to comment.