PHPackages                             dalpras/payment-paypal - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. dalpras/payment-paypal

ActiveLibrary[Payment Processing](/categories/payments)

dalpras/payment-paypal
======================

PayPal Orders v2 connector for dalpras/payment-core.

v0.5.0(2mo ago)02MITPHPPHP ^8.2

Since Apr 20Pushed 2mo agoCompare

[ Source](https://github.com/dalpras/payment-paypal)[ Packagist](https://packagist.org/packages/dalpras/payment-paypal)[ RSS](/packages/dalpras-payment-paypal/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (5)Versions (6)Used By (0)

dalpras/payment-paypal
======================

[](#dalpraspayment-paypal)

PayPal Orders v2 / Payments v2 connector for `dalpras/payment-core`.

Supported flow:

- create PayPal order
- redirect buyer to the approval link
- complete checkout by capturing or authorizing the order
- persist PayPal capture and authorization ids as normalized metadata
- capture authorized payments
- refund captured payments
- void authorizations through cancel
- sync order state
- parse and verify webhooks

Installation
------------

[](#installation)

```
composer require dalpras/payment-paypal
```

Dependencies
------------

[](#dependencies)

- `dalpras/payment-core`
- `psr/http-client`
- `psr/http-factory`
- `psr/http-message`

Bring your own PSR-18 client and PSR-17 factories.

Basic usage
-----------

[](#basic-usage)

```
use DalPraS\Payment\PayPal\Config\PayPalConfig;
use DalPraS\Payment\PayPal\Http\PayPalHttpClient;
use DalPraS\Payment\PayPal\Mapper\PayPalOrderMapper;
use DalPraS\Payment\PayPal\Provider\PayPalProvider;

$config = new PayPalConfig(
    clientId: 'sandbox-client-id',
    clientSecret: 'sandbox-client-secret',
    sandbox: true,
    webhookId: null,
    brandName: 'My Store',
);

$httpClient = new PayPalHttpClient(
    config: $config,
    httpClient: $psr18Client,
    requestFactory: $requestFactory,
    streamFactory: $streamFactory,
);

$provider = new PayPalProvider(
    config: $config,
    httpClient: $httpClient,
    mapper: new PayPalOrderMapper(),
);
```

Register the provider in `PaymentManager` through the core `ProviderRegistry`.

Checkout mapping
----------------

[](#checkout-mapping)

`CheckoutRequest` maps to `POST /v2/checkout/orders`.

Core fieldPayPal field`intent = sale``intent = CAPTURE``intent = authorize` / `capture_later``intent = AUTHORIZE`line items`purchase_units[0].items`amount breakdown`purchase_units[0].amount.breakdown``paymentReference``purchase_units[0].custom_id`return/cancel URLs`payment_source.paypal.experience_context`locale`payment_source.paypal.experience_context.locale`idempotency key`PayPal-Request-Id`Metadata returned by this provider
----------------------------------

[](#metadata-returned-by-this-provider)

### Checkout creation

[](#checkout-creation)

```
[
    'provider' => 'paypal',
    'provider_payment_id' => $paypalOrderId,
    'order_id' => $paypalOrderId,
    'paypal_order_id' => $paypalOrderId,
]
```

### Completion / authorization / sync

[](#completion--authorization--sync)

The provider extracts capture and authorization ids from PayPal order payloads:

```
[
    'provider' => 'paypal',
    'provider_payment_id' => $paypalOrderId,
    'order_id' => $paypalOrderId,
    'paypal_order_id' => $paypalOrderId,
    'capture_id' => $captureId,
    'paypal_capture_id' => $captureId,
    'authorization_id' => $authorizationId,
    'paypal_authorization_id' => $authorizationId,
]
```

Core stores these values and reuses them for future refund/capture/cancel operations.

Completion
----------

[](#completion)

`completeCheckout()` resolves the PayPal order id from:

1. `expectedProviderPaymentId`
2. `queryParams['token']`
3. `bodyParams['token']`
4. `metadata['paypal_order_id']`
5. `metadata['order_id']`

Then it chooses the final action from `expectedIntent`:

- `sale` -&gt; capture the order
- `authorize` / `capture_later` -&gt; authorize the order

When used through `PaymentManager`, `expectedProviderPaymentId`, `expectedIntent` and metadata are normally filled automatically from the stored `Payment`.

Refunds
-------

[](#refunds)

Refunds use `POST /v2/payments/captures/{capture_id}/refund`.

The provider resolves the capture id from:

1. `metadata['capture_id']`
2. `metadata['paypal_capture_id']`
3. `providerPaymentId`

Full refund:

```
$result = $paymentManager->refund(new RefundRequest(
    providerCode: 'paypal',
    paymentReference: $paymentReference,
    providerPaymentId: null,
    idempotencyKey: $refundId,
    metadata: [
        'description' => 'Customer refund',
    ],
));
```

Partial refund:

```
$result = $paymentManager->refund(new RefundRequest(
    providerCode: 'paypal',
    paymentReference: $paymentReference,
    providerPaymentId: null,
    idempotencyKey: $refundId,
    metadata: [
        'amount_decimal' => '50.00',
        'currency' => 'EUR',
        'description' => 'Partial refund',
    ],
));
```

Capturing authorized payments
-----------------------------

[](#capturing-authorized-payments)

Captures use `POST /v2/payments/authorizations/{authorization_id}/capture` when an authorization id is available.

```
$result = $paymentManager->capture(new CaptureRequest(
    providerCode: 'paypal',
    paymentReference: $paymentReference,
    providerPaymentId: null,
    idempotencyKey: $captureId,
    metadata: [
        'amount_decimal' => '50.00',
        'currency' => 'EUR',
        'description' => 'Capture authorized amount',
        'final_capture' => true,
    ],
));
```

Cancelling / voiding authorizations
-----------------------------------

[](#cancelling--voiding-authorizations)

`cancel()` voids an authorization when `authorization_id` or `paypal_authorization_id` is available. Through `PaymentManager`, that metadata is normally reused from completion/authorization.

```
$result = $paymentManager->cancel(new CancelRequest(
    providerCode: 'paypal',
    paymentReference: $paymentReference,
    providerPaymentId: null,
    idempotencyKey: $voidId,
    metadata: [
        'description' => 'Customer cancelled before capture',
    ],
));
```

Webhook verification
--------------------

[](#webhook-verification)

The provider builds PayPal's webhook verification payload from incoming headers and the configured webhook id. Configure `webhookId` in `PayPalConfig` before using `verifyWebhook()` in production.

Testing
-------

[](#testing)

```
composer install
vendor/bin/phpunit
```

Syntax check:

```
find src tests -name '*.php' -print0 | xargs -0 -n1 php -l
```

License
-------

[](#license)

MIT

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance87

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~7 days

Total

5

Last Release

64d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f4ad7c52ee1f0a8936e8bb6bcc95f15d4f55ce63233a0fa629da25bba024bd97?d=identicon)[dalpras](/maintainers/dalpras)

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/dalpras-payment-paypal/health.svg)

```
[![Health](https://phpackages.com/badges/dalpras-payment-paypal/health.svg)](https://phpackages.com/packages/dalpras-payment-paypal)
```

###  Alternatives

[tempest/framework

The PHP framework that gets out of your way.

2.2k34.4k16](/packages/tempest-framework)[flow-php/flow

PHP ETL - Extract Transform Load - Data processing framework

85036.3k](/packages/flow-php-flow)[cakephp/cakephp

The CakePHP framework

8.8k19.5M1.8k](/packages/cakephp-cakephp)[telnyx/telnyx-php

Official Telnyx PHP SDK — APIs for Voice, SMS, MMS, WhatsApp, Fax, SIP Trunking, Wireless IoT, Call Control, and more. Build global communications on Telnyx's private carrier-grade network.

36789.4k2](/packages/telnyx-telnyx-php)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[chargebee/chargebee-php

ChargeBee API client implementation for PHP

758.5M9](/packages/chargebee-chargebee-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
