+=head2 _revmap_fields
+
+Accepts I<%map> and sets the content field specified
+by map keys to be the value of the content field
+specified by map values, e.g.
+
+ ssl_merchant_id => 'login'
+
+will set ssl_merchant_id to the current value of login.
+
+Values may also be references to strings, e.g.
+
+ ssl_exp_date => \$expdate_mmyy,
+
+will set ssl_exp_date to the value of $expdate_mmyy.
+
+=cut
+
+sub _revmap_fields {
+ my ( $self, %map ) = @_;
+ my %content = $self->content();
+ foreach ( keys %map ) {
+ $content{$_} =
+ ref( $map{$_} )
+ ? ${ $map{$_} }
+ : $content{ $map{$_} };
+ }
+ $self->content(%content);
+}
+
+=head2 expdate_mmyy
+
+Accepts I<$expiration>. Returns mmyy normalized value,
+or original value if it couldn't be normalized.
+
+=cut
+
+sub expdate_mmyy {
+ my $self = shift;
+ my $expiration = shift;
+ my $expdate_mmyy;
+ if ( defined($expiration) and $expiration =~ /^(\d+)\D+\d*(\d{2})$/ ) {
+ my ( $month, $year ) = ( $1, $2 );
+ $expdate_mmyy = sprintf( "%02d", $month ) . $year;
+ }
+ return defined($expdate_mmyy) ? $expdate_mmyy : $expiration;
+}
+
+=head2 required_fields
+
+Accepts I<@fields> and makes sure each of those fields
+have been set in content.
+
+=cut
+
+sub required_fields {
+ my($self,@fields) = @_;
+
+ my @missing;
+ my %content = $self->content();
+ foreach(@fields) {
+ next
+ if (exists $content{$_} && defined $content{$_} && $content{$_}=~/\S+/);
+ push(@missing, $_);
+ }
+
+ Carp::croak("missing required field(s): " . join(", ", @missing) . "\n")
+ if(@missing);
+
+}
+