Business-Payr

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

Revision history for Business-Payr

0.02     2026-08-28
        - Fix POD issues

0.01     2026-04-13
        - First release
        - Support for /thirdparty/onboarding/ endpoint (onboard_user)
        - Support for /thirdparty/user-login/ endpoint (create_payment_session)
        - Support for /thirdparty/rotate-token/ endpoint (rotate_token)
        - Business::Payr::PaymentSession with iframe_html helper
        - Business::Payr::Webhook with HMAC-SHA256 signature verification
        - Business::Payr::Webhook::Payment for typed access to webhook payloads

README.md  view on Meta::CPAN

elsif ( $Payment->pending ) {
    warn "Payment " . $Payment->payment_id
        . " is pending: " . ( $Payment->pending_reason // 'unknown reason' );
}
```

# DESCRIPTION

`Business::Payr` is a client library for interacting with the Payr third-party
integration API. It handles the necessary authentication and transport logic,
allowing you to focus on just the endpoints you want to call.

Payr enables your users to pay their rent by card through an embedded payment
interface. With this library you can:

- **Onboard users** with their tenancy details and KYC documents
- **Create payment sessions** for seamless rent payments
- **Embed the payment iframe** directly into your platform
- **Rotate your server API token** for improved security
- **Verify and parse webhooks** for real-time payment notifications

README.md  view on Meta::CPAN


# DEBUGGING

Set `MOJO_CLIENT_DEBUG=1` for user agent and transport debug output.

# METHODS

## onboard_user

Onboard one or more users to the Payr platform with their tenancy details and
KYC documents. Calls the `/thirdparty/onboarding/` endpoint.

```perl
# Single user
$Payr->onboard_user( \%user_args );

# Batch onboarding
$Payr->onboard_user( [ \%user_one, \%user_two ] );
```

`$user_args` should be a hash reference (single user) or array reference of

README.md  view on Meta::CPAN

If a tenancy already exists (matched by `user_id`, `start_rent_date`,
`payment_reference`, and `address_1`), only `end_rent_date`, `amount`, and
`frequency` can be updated.

Returns `1` on success. Throws an exception on failure with a descriptive error
message including any field-level validation errors returned by the API.

## create_payment_session

Creates a temporary payment session token for an already-onboarded user.
Calls the `/thirdparty/user-login/` endpoint.

```perl
my $Session = $Payr->create_payment_session( 'john.smith@example.com' );
```

The user identified by `$email` must have been previously onboarded via
`onboard_user`, otherwise a `400` error is thrown.

Returns a `Business::Payr::PaymentSession` object. The session URL embedded
in that object is valid for **15 minutes**. Pass it to `->iframe_html` to
generate the HTML snippet required to embed the Payr payment interface.

Any issues here will result in an exception being thrown.

## rotate_token

Generates a new server API token, replacing the current one. Calls the
`/thirdparty/rotate-token/` endpoint. The old token remains valid for a grace
period of 7–15 days, allowing you to update your systems without downtime.

```perl
my $rotation = $Payr->rotate_token;

my $new_token  = $rotation->{token};
my $old_expiry = $rotation->{old_token_expiry};
```

Returns a hash reference with keys `token` (the new token string) and

lib/Business/Payr.pm  view on Meta::CPAN


    if ( $Payment->completed ) {
        # Payment was successful
    }

=head1 DESCRIPTION

L<Business::Payr> is a client library for interacting with the Payr
third-party integration API (L<https://docs.payr.com/>). It handles the
necessary authentication and transport logic, allowing you to focus on just
the endpoints you want to call.

Payr enables your users to pay their rent by card through an embedded payment
interface. With this library you can:

=over

=item *

B<Onboard users> with their tenancy details and KYC documents

lib/Business/Payr.pm  view on Meta::CPAN

use Business::Payr::PaymentSession;
use Carp qw/ croak /;

$Business::Payr::VERSION = '0.02';

=head1 METHODS

=head2 onboard_user

Onboard one or more users to the Payr platform with their tenancy details and
KYC documents. Calls the C</thirdparty/onboarding/> endpoint.

    # Single user
    $Payr->onboard_user( \%user_args );

    # Batch onboarding
    $Payr->onboard_user( [ \%user_one, \%user_two ] );

C<$user_args> should be a hash reference (single user) or array reference of
hash references (multiple users) containing the fields described at
L<https://docs.payr.com/onboarding>.

lib/Business/Payr.pm  view on Meta::CPAN

                . ( defined $agent_id ? "'$agent_id'" : 'undef' );
        }
    }

    return $self;
}

=head2 create_payment_session

Creates a temporary payment session token for an already-onboarded user.
Calls the C</thirdparty/user-login/> endpoint.

    my $Session = $Payr->create_payment_session( '[email protected]' );

The user identified by C<$email> must have been previously onboarded via
L</onboard_user>, otherwise a C<400> error is thrown.

Returns a L<Business::Payr::PaymentSession> object. The session URL embedded
in that object is valid for B<15 minutes>. Pass it to L<Business::Payr::PaymentSession/iframe_html>
to generate the HTML snippet required to embed the Payr payment interface:

lib/Business/Payr.pm  view on Meta::CPAN

    );

    return Business::Payr::PaymentSession->new(
        url => $response->{url},
    );
}

=head2 rotate_token

Generates a new server API token, replacing the current one. Calls the
C</thirdparty/rotate-token/> endpoint. The old token remains valid for a
grace period of 7-15 days, allowing you to update your systems without
downtime.

    my $rotation = $Payr->rotate_token;

    my $new_token  = $rotation->{token};
    my $old_expiry = $rotation->{old_token_expiry};

Returns a hash reference with the following keys:

lib/Business/Payr/PaymentSession.pm  view on Meta::CPAN

package Business::Payr::PaymentSession;

=head1 NAME

Business::Payr::PaymentSession - class representing a Payr payment session
returned by the C</thirdparty/user-login/> endpoint.

=head1 SYNOPSIS

    my $Session = $Payr->create_payment_session( '[email protected]' );

    # Embed the payment interface in your page
    print $Session->iframe_html;

    # Or build the URL yourself
    my $url = $Session->url;

lib/Business/Payr/PaymentSession.pm  view on Meta::CPAN

use namespace::autoclean;

use Carp qw/ confess /;

=head1 ATTRIBUTES

=over

=item url (Str, required)

The full iframe URL returned by the C</thirdparty/user-login/> endpoint,
including the session token and session ID as query parameters. This URL
is valid for B<15 minutes>.

Example:

    https://sandbox.mypayr.co.uk/third-party?token=abc123&session_id=def456

=back

=cut

lib/Business/Payr/Webhook.pm  view on Meta::CPAN


=head1 NAME

Business::Payr::Webhook - class for verifying and parsing Payr webhook
notifications.

=head1 SYNOPSIS

    use Business::Payr::Webhook;

    # In your webhook endpoint handler:
    my $Webhook = Business::Payr::Webhook->new(
        body      => $raw_request_body,        # raw POST body string
        signature => $x_payr_signature_header, # X-Payr-Signature header value
        secret    => $webhook_secret,          # your Payr webhook secret
    );

    # Signature is verified during construction - an exception is thrown
    # if the signature does not match. Always wrap in eval / try:

    my $Payment = eval { $Webhook->resource };

lib/Business/Payr/Webhook.pm  view on Meta::CPAN

and your platform. The signature is carried in the C<X-Payr-Signature> HTTP
header. Verification is performed automatically during object construction; an
exception is thrown if the signature is missing, incorrect, or the payload
cannot be parsed.

B<Important:> You should always pass the B<raw request body> string as the
C<body> argument, before any deserialisation. Re-serialising a parsed
structure may produce different byte sequences and will cause verification to
fail.

Contact B<support@mypayr.co.uk> to configure your webhook endpoint URL and
receive your webhook secret.

=head1 SIGNATURE VERIFICATION DETAILS

Payr signs webhook payloads as follows:

=over

=item 1.



( run in 1.484 second using v1.01-cache-2.11-cpan-364913b4093 )