NAME

WWW::PayPal - Perl client for the PayPal REST API

VERSION

version 0.001

SYNOPSIS

use WWW::PayPal;

my $pp = WWW::PayPal->new(
    client_id => $ENV{PAYPAL_CLIENT_ID},
    secret    => $ENV{PAYPAL_SECRET},
    sandbox   => 1,                    # default: 0 (live)
);

# Create an order (replaces SetExpressCheckout)
my $order = $pp->orders->create(
    intent         => 'CAPTURE',
    purchase_units => [{
        amount => { currency_code => 'EUR', value => '42.00' },
    }],
    return_url => 'https://example.com/paypal/return',
    cancel_url => 'https://example.com/paypal/cancel',
);

# Redirect the buyer here:
my $approve_url = $order->approve_url;

# After the buyer approves, capture the payment
# (replaces GetExpressCheckoutDetails + DoExpressCheckoutPayment)
my $captured = $pp->orders->capture($order->id);

print $captured->payer_email, "\n";
print $captured->fee_in_cent, "\n";

# Refund a capture
$pp->payments->refund($captured->capture_id,
    amount => { currency_code => 'EUR', value => '10.00' });

# --- Recurring subscriptions ---

# One-time merchant setup: product + plan (do this at deploy time)
my $product = $pp->products->create(
    name => 'VIP membership', type => 'SERVICE', category => 'SOFTWARE',
);
my $plan = $pp->plans->create_monthly(
    product_id => $product->id,
    name       => 'VIP monthly',
    price      => '9.99',
    currency   => 'EUR',
);

# Per-user: create a subscription, redirect the buyer
my $sub = $pp->subscriptions->create(
    plan_id    => $plan->id,
    return_url => 'https://example.com/paypal/sub/return',
    cancel_url => 'https://example.com/paypal/sub/cancel',
);
my $approve_url = $sub->approve_url;

# Later: lifecycle
$sub->refresh;
$sub->suspend(reason => 'user paused');
$sub->activate(reason => 'resumed');
$sub->cancel(reason   => 'user quit');

DESCRIPTION

WWW::PayPal wraps PayPal's REST API. The initial release covers the Checkout / Orders v2 flow (one-off product sales, replacing the legacy NVP ExpressCheckout dance) and the Billing Subscriptions v1 flow (recurring monthly/yearly payments).

Operation dispatch uses cached OpenAPI operation tables (see WWW::PayPal::Role::OpenAPI), so no spec parsing happens at runtime.

client_id

PayPal REST app client ID. Defaults to the PAYPAL_CLIENT_ID environment variable.

secret

PayPal REST app secret. Defaults to the PAYPAL_SECRET environment variable.

sandbox

When true, all requests go to api-m.sandbox.paypal.com. Defaults to the PAYPAL_SANDBOX environment variable.

base_url

API base URL. Derived from "sandbox" by default.

orders

Returns a WWW::PayPal::API::Orders controller for the Checkout / Orders v2 API.

payments

Returns a WWW::PayPal::API::Payments controller for captures, refunds and authorizations.

products

Returns a WWW::PayPal::API::Products controller for catalog products (the abstract "what you're selling", referenced by plans).

plans

Returns a WWW::PayPal::API::Plans controller for billing plans (the recurring-cycle definitions that subscriptions reference).

subscriptions

Returns a WWW::PayPal::API::Subscriptions controller for creating and managing per-user recurring subscriptions.

SEE ALSO

SUPPORT

Issues

Please report bugs and feature requests on GitHub at https://github.com/Getty/p5-www-paypal/issues.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.