Business-OnlinePayment-PayflowPro

 view release on metacpan or  search on metacpan

PayflowPro.pm  view on Meta::CPAN


        # As of 8/18/2009: CUSTCODE appears to be cut off at 18
        # characters and isn't currently reportable.  Consider storing
        # local customer ids in the COMMENT1/2 fields as a workaround.
        CUSTCODE        => 'customer_id',
        SHIPTOFIRSTNAME => 'ship_first_name',
        SHIPTOLASTNAME  => 'ship_last_name',
        SHIPTOSTREET    => 'ship_address',
        SHIPTOCITY      => 'ship_city',
        SHIPTOSTATE     => 'ship_state',
        SHIPTOZIP       => 'ship_zip',
        SHIPTOCOUNTRY   => 'ship_country',
    );

    # Reload %content as _revmap_fields makes our copy old/invalid!
    %content = $self->content;

    my @required = qw( TRXTYPE TENDER PARTNER VENDOR USER PWD );

    # NOTE: we croak above if transaction_type ne 'C'
    if ( $self->transaction_type() eq 'C' ) {    # credit card
        if ( defined( $content{'ORIGID'} ) && length( $content{'ORIGID'} ) ) {
            push @required, qw(ORIGID);
        }
        else {
            push @required, qw(AMT ACCT EXPDATE);
        }
    }

    $self->required_fields(@required);

    my %params = $self->get_fields(
        qw(
          VENDOR PARTNER USER PWD TRXTYPE TENDER ORIGID COMMENT1 COMMENT2
          ACCT CVV2 EXPDATE AMT
          FIRSTNAME LASTNAME NAME EMAIL COMPANYNAME
          STREET CITY STATE ZIP COUNTRY
          SHIPTOFIRSTNAME SHIPTOLASTNAME
          SHIPTOSTREET SHIPTOCITY SHIPTOSTATE SHIPTOZIP SHIPTOCOUNTRY
          CUSTCODE
          )
    );

    # get header data
    my %req_headers = %{ $self->headers || {} };

    # get request_id from %content if defined for ease of use
    if ( defined $content{"request_id"} ) {
        $self->request_id( $content{"request_id"} );
    }

    unless ( defined( $req_headers{"X-VPS-Request-ID"} ) ) {
        $req_headers{"X-VPS-Request-ID"} = $self->request_id();
    }

    unless ( defined( $req_headers{"X-VPS-VIT-Client-Certification-Id"} ) ) {
        $req_headers{"X-VPS-VIT-Client-Certification-Id"} =
          $self->client_certification_id;
    }

    unless ( defined( $req_headers{"X-VPS-Client-Timeout"} ) ) {
        $req_headers{"X-VPS-Client-Timeout"} = $self->client_timeout();
    }

    my %options = (
        "Content-Type" => "text/namevalue",
        "headers"      => \%req_headers,
    );

    # Payflow Pro does not use URL encoding for the request.  The
    # following implements their custom encoding scheme.  Per the
    # developer docs, the PARMLIST Syntax Guidelines are:
    # - Spaces are allowed in values
    # - Enclose the PARMLIST in quotation marks ("")
    # - Do not place quotation marks ("") within the body of the PARMLIST
    # - Separate all PARMLIST name-value pairs using an ampersand (&)
    # 
    # Because '&' and '=' have special meanings/uses values containing
    # these special characters must be encoded using a special "length
    # tag".  The "length tag" is simply the length of the "value"
    # enclosed in square brackets ([]) and appended to the "name"
    # portion of the name-value pair.
    #
    # For more details see the sections 'Using Special Characters in
    # Values' and 'PARMLIST Syntax Guidelines' in the PayPal Payflow
    # Pro Developer's Guide
    #
    # NOTE: we pass a string to https_post so it does not do encoding
    my $params_string = join(
        '&',
        map {
            my $key = $_;
            my $value = defined( $params{$key} ) ? $params{$key} : '';
            if ( index( $value, '&' ) != -1 || index( $value, '=' ) != -1 ) {
                $key = $key . "[" . length($value) . "]";
            }
            "$key=$value";
          } keys %params
    );

    my ( $page, $resp, %resp_headers ) =
      $self->https_post( \%options, $params_string );

    $self->response_code($resp);
    $self->response_page($page);
    $self->response_headers( \%resp_headers );

    # $page should contain name=value[[&name=value]...] pairs
    my $response = $self->_get_response( \$page );

    # AVS and CVS values may be set on success or failure
    my $avs_code;
    if ( defined $response->{"AVSADDR"} or defined $response->{"AVSZIP"} ) {
        if ( $response->{"AVSADDR"} eq "Y" && $response->{"AVSZIP"} eq "Y" ) {
            $avs_code = "Y";
        }
        elsif ( $response->{"AVSADDR"} eq "Y" ) {
            $avs_code = "A";
        }
        elsif ( $response->{"AVSZIP"} eq "Y" ) {
            $avs_code = "Z";
        }

PayflowPro.pm  view on Meta::CPAN

=head1 DESCRIPTION

This module is a back end driver that implements the interface
specified by L<Business::OnlinePayment> to support payment handling
via the PayPal's Payflow Pro Internet payment solution.

See L<Business::OnlinePayment> for details on the interface this
modules supports.

=head1 Standard methods

=over 4

=item set_defaults()

This method sets the 'server' attribute to 'payflowpro.paypal.com'
and the port attribute to '443'.  This method also sets up the
L</Module specific methods> described below.

=item submit()

=back

=head1 Unofficial methods

This module provides the following methods which are not officially
part of the standard Business::OnlinePayment interface (as of 3.00_06)
but are nevertheless supported by multiple gateways modules and
expected to be standardized soon:

=over 4

=item L<order_number()|/order_number()>

=item L<avs_code()|/avs_code()>

=item L<cvv2_response()|/cvv2_response()>

=back

=head1 Module specific methods

This module provides the following methods which are not currently
part of the standard Business::OnlinePayment interface:

=head2 client_certification_id()

This gets/sets the X-VPS-VITCLIENTCERTIFICATION-ID which is REQUIRED
and defaults to "ClientCertificationIdNotSet".  This is described in
Website Payments Pro HTTPS Interface Developer's Guide as follows:

"A random globally unique identifier (GUID) that is currently
required. This requirement will be removed in the future. At this
time, you can send any alpha-numeric ID up to 32 characters in length.

NOTE: Once you have created this ID, do not change it. Use the same ID
for every transaction."

=head2 client_timeout()

Timeout value, in seconds, after which this transaction should be
aborted.  Defaults to 45, the value recommended by the Website
Payments Pro HTTPS Interface Developer's Guide.

=head2 debug()

Enable or disble debugging.  The value specified here will also set
$Business::OnlinePayment::HTTPS::DEBUG in submit() to aid in
troubleshooting problems.

=head2 expdate_mmyy()

The expdate_mmyy() method takes a single scalar argument (typically
the value in $content{expiration}) and attempts to parse and format
and put the date in MMYY format as required by PayflowPro
specification.  If unable to parse the expiration date simply leave it
as is and let the PayflowPro system attempt to handle it as-is.

=head2 request_id()

It is recommended that you specify your own unique request_id for each
transaction in %content.  A request_id is REQUIRED by the PayflowPro
processor.  If a request_id is not set, then Digest::MD5 is used to
attempt to generate a request_id for a transaction.

=head2 Deprecated methods

The following methods are deprecated and may be removed in a future
release.  Values for vendor and partner should now be set as arguments
to Business::OnlinePayment->new().  The value for cert_path was used
to support passing a path to PFProAPI.pm (a Perl module/SDK from
Verisign/Paypal) which is no longer used.

=over 4

=item vendor()

=item partner()

=item cert_path()

=item cvv2_code()

=back

=head1 Settings

The following default settings exist:

=over 4

=item server

payflowpro.paypal.com or pilot-payflowpro.paypal.com if
test_transaction() is TRUE

=item port

443

=back



( run in 1.784 second using v1.01-cache-2.11-cpan-39bf76dae61 )